Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
901 views
in Technique[技术] by (71.8m points)

overriding - Why is my override method not being called in C++?

So I have a base class that is made to hold a string value, and be able to add characters onto it:

class TextInput
{
public:
    std::string value;
    void add(char c) 
    {
        if (!value.empty()) 
        {
            value += c;
        }
        else
        {
            value = c;
        }
    }

    std::string getValue() 
    {
        return value; 
    }
};

Then an inherited class, which is the same as parent but should only allow you to add numeric values to the string:

class NumericInput : public TextInput 
{
public:
    TextInput input;
    void add(char c)
    {
        if (isdigit(c)) 
        {
            input.add(c);
        }
    }

    std::string getValue()
    {
        return value;
    }
};

What I want to know is, when called like this in my tests:

#ifndef RunTests
int main()
{
    TextInput* input = new NumericInput();
    input->add('1');
    input->add('a');
    input->add('0');
    std::cout << input->getValue();
}
#endif

Why does the call to add still only use the base add class? I would assume this to use the child NumericInout class since it is being created as one, but when debugging it still only uses the parent class and I don't understand why?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
class NumericInput : public TextInput 
{
public:
    TextInput input;

This is almost definitely not what you want. If you're inheriting, I can't think of a good reason you'd ever also want composition. Get rid of this input member variable. When you inherit, you already get everything from the parent class (including value in this case).

To specifically call the parent class's add(), you can do TextInput::add(), so your child add could look like:

void add(char c)
{
    if (isdigit(c)) 
    {
        TextInput::add(c); // Call parent add()
    }
}

Furthermore, if you want to call add() on a TextInput pointer that's pointing to a NumericInput, and you want it to resolve to call the NumericInput's add(), you must declare the base add() to be virtual:

virtual void add(char c) { // ...

Lastly, you can still append to a string even if there's nothing in it, so your check in the base add() does nothing.

Altogether, that'll make your code look like:

class TextInput
{
public:
    std::string value;
    virtual void add(char c)  { value += c; }
    std::string getValue() { return value; }
};

class NumericInput : public TextInput 
{
public:
    void add(char c)
    {
        if (isdigit(c)) { TextInput::add(c); }
    }

    // You already get this for free from the inheritance
    // std::string getValue()
    // {
    //     return value;
    // }
};

Live example here: https://ideone.com/kQxAPo


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...