C ++: overriding a protected method that is called by another method

I have a very simple question regarding 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(); 

prints nothing, so foo () obviously didn’t call a new defined print (). Is this allowed only with virtual methods?

+7
source share
5 answers

Yes, for this you need to make print virtual. Otherwise, A::foo does not know that descendants can provide alternative print implementations, happily invokes version A The compiler can even embed print inside foo when compiling A code, which makes the implementation in B completely inappropriate.

+7
source

For a derived class to override a function, the function must be declared virtual in the base class. This means that the call function is selected at runtime 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 repeating template pattern” (CRTP) to bring the knowledge of the derived type to the base class (which should 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; } }; 
+4
source

Yes, you can use virtual methods to make this example work, but you can also use CRTP .

+2
source

The answer to your question: "Is this only solvable using virtual methods?" is: no, this is possible without using virtual methods.

All you have to do is copy the foo() method to body B

 class B : public A { public: void foo() { print(); } protected: void print() { std::cout << "test" << std:: endl; } }; 

There.

+1
source

Yes, you cannot solve it without virtual methods or rewrite void foo()

because when compiling A he knows nothing about B , so he cannot call his method

0
source

All Articles