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?
Yes, the protected method of a superclass can be overridden by a subclass. If the superclass method is protected, the subclass overridden method can have protected or public (but not default or private) which means the subclass overridden method can not have a weaker access specifier.
Yes, an overridden method can have a different access modifier but it cannot lower the access scope. Methods declared public in a superclass also must be public in all subclasses. Methods declared protected in a superclass must either be protected or public in subclasses; they cannot be private.
You cannot override a non-virtual or static method. The overridden base method must be virtual , abstract , or override . An override declaration cannot change the accessibility of the virtual method.
No, we cannot override private or static methods in Java.
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.
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; }
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With