It seems that it is good to make the virtual methods private in order to separate the interfaces for following two clients - 1. clients that instantiate an object and call the method 2. clients that derive from the class and may want to override the method. Simply put - the first client does not need to know if a method is virtual. He will call the base class public non-virtual method which in turn will call the private virtual method. See code below for example.
Now in the case where the virtual method needs to super-message its base class' corresponding virtual method such as say a Save method - which has to pass through all virtual methods in the chain of inheritance in order to save data corresponding to each level of derivation - we have no option but to use a protected virtual method - unless there is a way to guarantee saving of data at all levels of derivation without using super messaging (there is none that I know).
I would like to know if above reasoning correct.
Make sure you use the scroll to see the entire code.
#include <iostream>
using namespace std;
class A {
string data;
protected:
virtual void SaveData()= 0;
public:
A():data("Data of A"){}
void Save(){
cout << data << endl;
SaveData();
}
};
class B : public A {
string data;
protected:
virtual void SaveData() { cout << data << endl;}
public:
B():data("Data of B") {}
};
class C : public B {
string data;
protected:
virtual void SaveData() {
B::SaveData();
cout << data << endl;
}
public:
C():data("Data of C") {}
};
int main(int argc, const char * argv[])
{
C c;
c.Save();
return 0;
}
It's difficult to tell what you're asking, but from the example, you do not need to make the method protected. It actually can be private. For details about the subtleties see this post: What is the point of a private pure virtual function?.
So long as you're not calling the private member from derived class (or outside classes), you're ok. Overriding of private members is ok. It does sound quite naughty and wrong that you can override your parent's privates, but in c++ you're allowed to do this.
The following should be ok:
You are exactly right:
virtual
methods not bepublic
private
therefore
protected
is the obvious solution, at least in C++03. Unfortunately it means you have to trust the derived class developer not to forget to call "super".In C++11, you can use
final
to prevent a derived class from overriding avirtual
method; it means though that you are forced to introduce a new hook, example:Of course, there is the trouble of having to come up with a new name each and every time... but at least you are guaranteed that
Child::saveImpl
will be called because none of its children can override it.Yes, if you need to call the SaveData of another class, it needs to be accessible from that class - so
public
orprotected
.