when doing
#include <string>
class MyString : public std::string
{
public:
MyString() {}
};
But the usage below:
MyString s = "Happy day";
MyString s("Happy Day");
MyString s = (MyString)"Happy day";
neither of them works.
It seems that there's something to do with constructors/operators declaration/overridding, but can anyone help point out where may I find these resources?
Thanks.
std::string
isn't designed for inheritance. It doesn't have any virtual functions (not even the destructor!), so you can't override anything. It also doesn't have a protected interface, so you gain nothing from subclassing that you couldn't get by making some standalone utility functions that takestd::string
.Keep in mind that most STL implementations expect you to use
std::string
with copy semantics, not reference semantics, and this makes the case for adding inherited fields or overriding functions even weaker.If you really want something like
std::string
with extra functions, you could consider using composition instead of inheritance, but this isn't great either. You don't have to worry about thestd::string
destructor not getting called properly, but you do end up having to wrap a lot of methods fromstd::string
that you need, which is tedious. Also, your utility functions will only work with MyString when most code is going to expectstd::string
, so it isn't very reusable.You're better off making some utility functions that take
std::string
. Or, ifstd::string
isn't providing what you need, you should go with some other string implementation that suits your needs. Here are some possibilities that come to mind:std::rope
. It's in GNU C++, so maybe you can rely on it.The bottom line is that you shouldn't do this. The destructor on
std::string
isn't virtual. This means that if you do the following:The only way this might be safe is if you don't add members to your string. You might think that you don't need any now, but someone who isn't aware of these issue may come along later (or you, when you've forgotten this advice perhaps) and add one, and then hey presto, you have a difficult to track down memory leak.
You need to define some constructors for the different types that you want to be able to convert into your strings. These constructors can basically just hand the parameters through to the underlying
std::string
.If you don't manually create them, the compiler creates a default- and a copy-constructor for you:
To allow construction from string literals, you need a constructor that takes a
const char*
:A constructor that takes a
const std::string&
would also be useful to convertstd::string
s to your string type. If you want to avoid implicit conversions of normal strings, you should make itexplicit
:(Edited because my original version was full of errors and I can't delete the accepted answer)
You're defining a ctor MyString that takes no arguments. If overrides the other ctors, so there's no ctor taking a string argument at all.
You need to ctor of one argument of type
const char *
, something like(Don't trust the syntax, look it up; I don't write C++ every day any longer.)
Check the section in the C++ FAQ Lite on ctors.
(Oops. Const char *, not string. Told you I didn't write C++ every day.)
The problem is that you need to overload the constructor that takes const char* and call the base class constructor as follows:
All three of your tests should work then.
std::string isn't intended to be inherited from. It doesn't have any virtual methods so you can't override any of its methods.
You should look into composition. Or simply creating utility functions which operate on std::strings