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.