简体   繁体   中英

Class Inheritance: use parent's function on child's member

I have two classes PARENT and CHILD , where the latter inherits from its parent a function that uses a private constant member value. I expected it to use the member value of the child, but instead it uses the parent's value, unless I redefine the function in the child again (see CHILD2 ).

An easy solution would be to redefine the function in each child (I expect to have maybe 10 children-types), but that doesn't seem right to me.

To make it a bit clearer, here is a minimum working example:

#include <iostream>
#include <string>

// PARENT Class that has a function to talk
class PARENT {
public:
    void talk() {
        std::cout << "Hello my name is " << name.c_str() << "\n";
    }
private:
    const std::string name = "Parent";
};


// CHILD Class, inherits from PARENT, but should use the different name
class CHILD : public PARENT {
private:
    const std::string name = "Child";
};


// CHILD2 Class, that redefines the talk-function
class CHILD2 : public PARENT {
public:
    void talk() {
        std::cout << "Hello my name is " << name.c_str() << "\n";
    }
private:
    const std::string name = "Child2";
};


int main() {
    PARENT parent;
    CHILD child;
    CHILD2 child2;

    parent.talk(); // expected 'Hello my name is Parent' // GOOD
    child.talk();  // expected 'Hello my name is Child'  // BAD, it uses 'Parent'
    child2.talk(); // expected 'Hello my name is Child2' // GOOD
    return 0;
}

Is there a way to use the talk() -function on the child's name , without re-declaring the function for each child-class?

You just keep adding std::string members. That's wasteful to begin with, and is the cause of you looking for a workaround. Instead of default initializing all those new strings, allow a child class to provide a value for it in the parent. Add a protected constructor:

// PARENT Class that has a function to talk
class PARENT {
public:
    void talk() {
        std::cout << "Hello my name is " << name << "\n";
    }

    PARENT() = default; // To still allow default construction as before

protected:
    explicit PARENT(std::string const& name) : name(name) {}

private:
    const std::string name = "Parent";
};

And use it in each child class constructor. Now there's only one talk function, and each child is allowed a customization point.

class CHILD : public PARENT {
public:
    CHILD() : PARENT("Child") {}
};

只在父级中保留一个name变量,将其传递给PARENT的构造函数,将其初始化为您想要在子级中使用的名称,并且不要覆盖talk

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM