Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Overriding a protected method which is called by another method

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?

like image 784
ph4nt0m Avatar asked Jul 21 '12 13:07

ph4nt0m


People also ask

Can you override a protected method?

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.

When you use method overriding Can you change the access level of the method from protected to public why?

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.

Can we override protected method in C#?

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.

Can I override public method with private Java?

No, we cannot override private or static methods in Java.


2 Answers

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.

like image 98
Sergey Kalinichenko Avatar answered Oct 25 '22 08:10

Sergey Kalinichenko


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; }
};
like image 35
Mike Seymour Avatar answered Oct 25 '22 08:10

Mike Seymour