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!
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.
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.
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.
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.
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.
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.
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