using namespace std;
#include <cstdio>
#include <iostream>
class One{
private:
virtual void func(){
cout<<"bark!"<<endl;
}
};
class Two: public One{
public:
void func(){
cout<<"two!"<<endl;
}
};
int main(){
One *o = new Two();
o->func();
}
Why is there an error on o->func()
?
I don't know the mechanism behind it... In my opinion, o->func()
should call the func()
in the derived class, which is public, so there wouldn't be problems, but it says:
error: ‘virtual void One::func()’ is private
Accessibility check is performed based on the static type of the object. The type of
o
isOne*
. This means that ifOne::func()
isprivate
, theno->func()
won't compile.On the other hand, which virtual member function will be called (i.e. dynamic dispatch) happens at run-time, based on the dynamic type of the object. So if
One::func()
ispublic
,o->func()
will callTwo::func()
, becauseo
is pointing to an object of typeTwo
.For your sample code and use case, making
One::func()
private
is just meaningless. But note that there's a famous idiom called Non-Virtual Interface, which makes use ofprivate
virtual member functions of base class.Other suggestions:
delete o;
Add a virtual destructor in the base class
One
. Otherwisedelete o;
will lead to undefined behavior; e.g. the destructor ofTwo
might not be invoked.A subclass can't ease inheritance restriction, even though func is virtual, it is still the inheritance restrictions remain.
please see this answer for compliated view of inheritance restrictions :
Difference between private, public, and protected inheritance
Please check Access specifiers and virtual functions.
From standard :
If name lookup determines a viable function to be a virtual function, the access specifier of the virtual function is checked in the scope of the static type of the object expression used to name the function. At run time, the actual function to be called could be defined in the derived class with a completely different access specifier. This is because 'access specifiers' are a compile time phenomenon.
Since access specifier of function
func()
is checked in the scope ofOne *o
, and it is private in classOne
, it produces error.If
One
declaresfunc()
as public, andTwo
declares it private, there won't be any errors. See this Private function invoked and it works. Could any of you reason it please