问题
Suppose you wanted to reproduce the following Python snippet:
class Base:
name = "base"
def announce(self):
print(self.name)
class Derived(Base):
name = "derived"
Base().announce()
Derived().announce()
... which would output:
"base"
"derived"
Initially, you may be inclined to write something like the following:
#include <iostream>
#include <string>
struct Base {
std::string name = "base";
void announce() {
std::cout << name << std::endl;
}
};
struct Derived : public Base {
std::string name = "movie";
};
int main() {
Base().announce();
Derived().announce();
return 0;
}
But here Derived.name simply shadows Base.name. Calling Derived.announce() references Base.name and prints "base".
Is there any way to implement this behaviour? Ideally without class templates if possible.
回答1:
C++ doesn't work like Python (which isn't surprising, they are two very different languages after all), and member variables defined in an inherited class really defines a new variable that is unrelated to the variables of the parent class.
One possible solution is to create a second (possibly protected) Base constructor which takes the name as an argument, and then the Derived class can use it to initialize the member:
struct Base {
Base() = default; // A defaulted default constructor
std::string name = "base";
void announce() {
std::cout << name << std::endl;
}
protected:
explicit Base(std::string name)
: name{ std::move(name) } // Initialize the member
{
}
};
struct Derived : public Base {
Derived()
: Base("movie") // Initialize the base class using the special constructor
{
}
};
The default Base default constructor is needed, because if you declare another constructor the compiler won't automatically generate a default constructor for you.
来源:https://stackoverflow.com/questions/61314511/how-does-attribute-inheritance-in-c-work