Reputation: 133
Recently, I have been wanting to define a subclass spstring of std::string. It declared in spstr.h:
#include <cctype>
#include <string>
#include <algorithm>
#include <sstream>
#include <stdint.h>
#include <xstring>
class spstring : public std::string {
public:
spstring(std::string s):std::string(s){} //Declare the constructor
int stoi(); //Declare stoi
spstring Spstring(std::string s); ////Declare mandatory conversion function
};
spstring spstring::Spstring(std::string s)
{
spstring spstr(s);
return(spstr);
}
However, when tested in main.cpp:
spstring byteaddstr(std::string(argv[4])); //convertchar* to spstring
int byteadd;
byteadd=byteaddstr.stoi(); //call byteaddstr.stoi
it failed to be complied for:
error C2228: left of “.stoi” must have class/struct/union
Sounds strange, since byteaddstr indeed an instance of spstring, why cannot call its member function?
Upvotes: 3
Views: 1566
Reputation: 234695
Inheriting from std::string
(and the STL containers) is a bad idea. They are not designed to operate as base classes.
Importantly, they don't necessarily have a virtual destructor so that can make memory management difficult for derived classes.
You would also lose readability too: If I see an STL class or function then I know exactly what is going to happen as it's assumed that I've memorised the standard. With a derived class I have to rely on its documentation or program comments.
So my answer: There is no right way to inherit from std::string.
Upvotes: 1
Reputation: 145269
In C++ any declaration that can be parsed as a function declaration, such as …
spstring byteaddstr(std::string(argv[4])); //convertchar* to spstring
is parsed as a function declaration.
I.e. not a variable.
One solution in this particular case, is to add extra parentheses:
spstring byteaddstr(( std::string(argv[4]) )); //convertchar* to spstring
This is known as the most vexing parse in C++, although some people disagree about whether Scott Meyers' original use of that term applies as generally as it's used now.
And by the way, one should generally have a pretty good reason to derive from std::string
, because it adds complexity and confusion (you can safely disregard concerns about dynamic allocation, because code that dynamically allocates std::string
deserves whatever it gets). So, I suggest that you don't do that.
Upvotes: 5