C++: Overriding a protected method which is called by another method
Solution 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.
Solution 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; }
};
Solution 3
Yes you can virtual methods to make this example work, but you can also use CRTP.
Solution 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.
Related videos on Youtube
ph4nt0m
Updated on August 30, 2022Comments
-
ph4nt0m over 1 year
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?
-
Mr Lister almost 12 yearsQuestion: why are you trying to avoid virtual methods? If you explain why, maybe we can help.
-
ph4nt0m almost 12 yearsThe problem is that the class A (which I want to modify) is part of a library. So I have no real chance of making the method virtual if I don't want to modify the library itself. I think the easiest workaround will be your suggestion of copying the calling method into my subclass.
-
-
Nawaz almost 12 years+1 for CRTP solution. (BTW, it is "curiously recurring (not recursive) template pattern")
-
Ramakrishnan Kannan almost 8 yearsIn my humble opinion, here A is like a standard interface from the provider. The provider expects the consumer to override and provide a callback function that the consumer can use.
-
Mr Lister almost 8 years@RamakrishnanKannan Yes, but according to the OP's comment to the question, they were in a situation where A was ineffective, yet A could not be changed to make the function virtual.