Welcome to JiKe DevOps Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
885 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

Please log in or register to answer this question.

1 Answer

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to JiKe DevOps Community for programmer and developer-Open, Learning and Share
...