Lukas Pettersson
Lukas Pettersson

Reputation: 31

setting an std::string data member from a derived class constructor

I have a derived class called Mystring that is derived from std::string, and I would like to set the value of the string that I am working with.

From my understanding to access the string object from std::string I would use *this to get the string that I am currently working with.

I would like to set *this to a string of my choosing, I did this my setting *this = n; but it crashes my code and returns a "Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffeef3ffff8)" my code is below:

So my question is, how can I set the value of std::string to something through my derived class. Much thanks!

class Mystring : public std::string
{
public:
    Mystring(std::string n);
    std::string removePunctuation();
    std::string toLower();


};
Mystring::Mystring(std::string n)
{
    *this = n;
}
std::string Mystring::removePunctuation()
{
    long int L = length();

    char *cstr = new char[L + 1];
    strcpy(cstr, c_str());
    //cout << cstr[L-1] << endl; // last character of c string
    if(!isalpha(cstr[L-1]))
    {
        pop_back() ;
    }

    return *this;
}
std::string Mystring::toLower()
{

    long int L = length();

    char *cstr = new char[L + 1];
    strcpy(cstr, c_str());

    for(int i = 0; i < L;i++)
    {
        int buffer = cstr[i];
        cstr[i] = tolower(buffer);
        std::cout << cstr[i];


    }
    std::string returnstring(cstr);
    delete [] cstr;

    return returnstring;
}
int main() {
    Mystring temp("dog");
    std::cout << "Hello World";
    return 0;
}

Upvotes: 0

Views: 103

Answers (2)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385144

Style aside, the fundamental idea of using an assignment operator to "reset" an inherited subobject is not necessarily incorrect.

However, a conversion is required to get from std::string (the type of the RHS) to Mystring (the type of the LHS, i.e. *this). The only way to perform that conversion is to use the constructor Mystring(std::string). Except… you're already in it. Hence that function is effectively recursive and will repeat forever until you exhaust your stack.

Stack filling up

You need to upcast *this to a std::string in order to make this work:

static_cast<std::string&>(*this) = n;

I do agree with the other people here that you shouldn't be deriving from std::string, and certainly not just to add a couple of utility functions that ought to be free functions taking std::string (perhaps in a nice namespace, though?).

Upvotes: 3

Jerry Coffin
Jerry Coffin

Reputation: 490108

Don't do it. Derivation provides no benefit in this situation.

Create your added functions as free functions that operate on a string. For example:

void remove_punctuation(std::string &s) { 
    if (!std::isalpha(s.back()))
        s.pop_back();
}

void tolower(std::string &s) { 
    for (auto &c : s)
        c = std::tolower(c);
}

Making either/both of these a member function serves no purpose and provides no benefit.

References

Upvotes: 0

Related Questions