Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

virtual function in private or protected inheritance

Tags:

c++

It's easy to understand the virtual function in public inheritance. So what's the point for virtual function in private or protected inheritance?

For example:

class Base {
public:
virtual void f() { cout<<"Base::f()"<<endl;}
};

class Derived: private Base {
public: 

void f() { cout<<"Derived::f()"<<endl;}

};

Is this still called overriding? What's the use of this case? What's the relationship of these two f()?

Thanks!

like image 338
skydoor Avatar asked Jan 28 '10 20:01

skydoor


People also ask

Are virtual functions public or private?

A virtual function can be private as C++ has access control, but not visibility control. As mentioned virtual functions can be overridden by the derived class but under all circumstances will only be called within the base class.

Can virtual function be inherited?

Base classes can't inherit what the child has (such as a new function or variable). Virtual functions are simply functions that can be overridden by the child class if the that child class changes the implementation of the virtual function so that the base virtual function isn't called. A is the base class for B,C,D.

Can a virtual method be protected?

Yes, if you need to call the SaveData of another class, it needs to be accessible from that class - so public or protected . Show activity on this post. NVI (Non-Virtual Interface) requires that virtual methods not be public. Calling the base class method requires that it not private.

Do virtual functions have to be public?

Virtual functions, in their view, should never be public, because they define the class' interface, which must remain consistent in all derived classes. Protected and private virtuals define the class' customizable behavior, and there is no need to make them public.


2 Answers

Private inheritance is just an implementation technique, not an is-a relationship, as Scott Meyers explains in Effective C++:

class Timer {
public:
    explicit Timer(int tickFrequency);
    virtual void onTick() const; // automatically called for each tick
    ...
};

class Widget: private Timer {
private:
    virtual void onTick() const; // look at Widget private data
    ...
};

Widget clients shouldn't be able to call onTick on a Widget, because that's not part of the conceptual Widget interface.

like image 55
fnieto - Fernando Nieto Avatar answered Nov 15 '22 18:11

fnieto - Fernando Nieto


Your f() method is still overridden. This relationship is useful when implementing the Template Method design pattern. Basically, you'd implement common sets of operations in the base class. Those base class operations would then invoke a virtual method, like your f(). If the derived class overrides f(), the base class operations end up calling the derived version of f(). This allows derived classes to keep the base algorithm the same but alter the behavior to suit their needs. Here's a trivial example:

#include <iostream>

using namespace std;

class Base
{
public:
  virtual void f() { cout<<"Base::f()" << endl; }
protected:
  void base_foo() { f(); }
};

class DerivedOne: private Base
{
public: 
  void f() { cout << "Derived::f()" << endl;}
  void foo() { base_foo(); }
};

class DerivedTwo: private Base
{
public: 
  void foo() { base_foo(); }
};

int main()
{
  DerivedOne d1;
  d1.foo();

  DerivedTwo d2;
  d2.foo();
}

Here's the result at run-time:

$ ./a.out 
Derived::f()
Base::f()

Both derived classes call the same base class operation but the behavior is different for each derived class.

like image 39
Void Avatar answered Nov 15 '22 18:11

Void