问题
I have a very basic question concerning inheritance in C++:
class A
{
public:
void foo() { print(); }
protected:
void print() {}
};
class B : public A
{
protected:
void print() { std::cout << "test" << std:: endl; }
};
Now the following code
B b;
b.foo();
doesn't print anything, so foo() obviously didn't call the newly defined print(). Is this only solvable by using virtual methods?
回答1:
Yes, you need to make print virtual in order for this to work. Otherwise, A::foo has no idea that descendants could provide alternative implementations of print, an happily calls A's version. Compiler may even inline the print inside foo at the time A's code is compiled, making the implementation in B completely irrelevant.
回答2:
In order for the derived class to override a function, the function must be declared virtual in the base class. That means that the function to call is chosen at run-time, when the function is called, according to the dynamic type of the object.
An alternative to overriding, if the derived type of each object is known at compile time, is to use the so-called "curiously recurring template pattern" (CRTP) to inject knowledge of the derived type into the base class (which must become a template to support this):
template <typename Derived> class A
{
public:
void foo() { static_cast<Derived*>(this)->print(); }
};
class B : public A<B>
{
private:
friend class A<B>; // assuming you don't want to make the function public
void print() { std::cout << "test" << std:: endl; }
};
回答3:
Yes you can virtual methods to make this example work, but you can also use CRTP.
回答4:
The answer to your question, "Is this only solvable by using virtual methods?" is: no, it is possible without using virtual methods.
All you need to do is copy the foo() method over to the body of B.
class B : public A
{
public:
void foo() { print(); }
protected:
void print() { std::cout << "test" << std:: endl; }
};
There.
回答5:
Yes, you can't solve it without virtual methods or rewriting void foo()
because when A is compiling it doesn't know anything about B, so it can't call its method
来源:https://stackoverflow.com/questions/11592809/c-overriding-a-protected-method-which-is-called-by-another-method