Public virtual function derived private in C++

╄→гoц情女王★ 提交于 2019-12-17 15:33:41

问题


I was trying to figure out what happens when a derived class declares a virtual function as private. The following is the program that I wrote

#include <iostream>
using namespace std;
class A
{
    public:
        virtual void func() {
        cout<<"A::func called"<<endl;
    }
    private:
};
class B:public A
{
    public:
    B()
    {
        cout<<"B constructor called"<<endl;
    }
    private:
    void func() {
        cout<<"B::func called"<<endl;
    }
};
int main()
{
    A *a = new B();
    a->func();
    return 0;
}

Surprisingly (for me) the output was:

B constructor called
B::func called

Isn't this violating the private access set for that function. Is this the expected behavior? Is this is a standard workaround or loophole? Are access levels bypassed when resolving function calls through the VTABLE?

Any insight in to this behavior would be greatly helpful.

Further it was mentioned that a privately overriding a virtual member would prevent further classes from inheriting it. Even this is having problems. Modifying the above program to include:

class C: public B
{
    public:
    void func() {
        cout<<"C::func called"<<endl;
    }
};

and the main test program to:

int main()
{
    A *a = new C();
    a->func();
    return 0;
}

output is:

C::func called

回答1:


The behavior is correct. Whenever you declare your function as "virtual", you instruct the compiler to generate a virtual call, instead of the direct call to this function. Whenever you override the virtual function in the descendant class, you specify the behavior of this function (you do not change the access mode for those clients, who rely on the "parent's" interface).

Changing the access mode for the virtual function in the descendant class means that you want to hide it from those clients, who use the descendant class directly (who rely on the "child's" interface).

Consider the example:

void process(const A* object) {
   object->func();
}

"process" function relies on the parent's interface. It is expected to work for any class, public-derived from A. You cannot public-derive B from A (saying "every B is A"), but hide a part of its interface. Those, who expect "A" must receive a fully functional "A".




回答2:


This is well-defined behavior. If a were a B* this wouldn't compile. The reason is that member access is resolved statically by the compiler, not dynamically at run-time. Many C++ books suggest that you avoid coding like this because it confuses less experienced coders.




回答3:


Well, you are calling A::func() which is public though in a B object it is overridden by B::func(). This is a common pattern with the following implications:

  • func is not intended to be called on derived B objects

  • func cannot be overridden in classes derived from B



来源:https://stackoverflow.com/questions/1061726/public-virtual-function-derived-private-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!