3

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?

6
  • 8
    You generally don't want to derive from STL containers. Commented Dec 11, 2013 at 7:00
  • 2
    In general, it is considered a bad idea to inherit from std::string, especially publicly (see related SO post). Private inheritance might be considered safe enough, although it still imposes a tight coupling between your class and std::string. See an interesting discussion on abuses of inheritance here. As for the error, please post a short, self-contained example that reproduces the problem. Commented Dec 11, 2013 at 7:10
  • 1
    You don't derive from std::string (or map, or vector, or any other container). In all instances where I encountered this there were several better solutions available. Whenever you need to derive from an stl container, consider encapsulation instead, meaning either using the container as a member of your class, or using private inheritance. Commented Dec 11, 2013 at 7:17
  • Note that passing std::string by value is inefficient, use const reference or move syntax instead. Commented Dec 11, 2013 at 7:24
  • 1
    With regards to using STL containers to define new types, composition is the best approach than inheritance. See here: stackoverflow.com/questions/14089088/… Commented Dec 11, 2013 at 7:25

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, this is the buttom line. Thanks a lot!
So, what exactly are problems regarding the inheritance, if we disregard concerns about dynamic allocation? My understanding is that inheritance makes the code more complex and harder to understand. Is there more to it?
@BЈовић: not really, imo. but those properties translate to more work.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.