公共虚拟函数派生私人在C + + [英] Public virtual function derived private in C++

查看:191
本文介绍了公共虚拟函数派生私人在C + +的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道当一个派生类将一个虚函数声明为private时会发生什么。以下是我写的程序

  #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;令人惊讶的是(对我来说)输出是:

  B构造函数称为
B :: func调用

这不会违反该函数的私有访问集。这是预期的行为吗?这是标准的解决方法还是漏洞?在通过VTABLE解析函数调用时,访问级别是否被绕过?



对此行为的任何洞察都将非常有帮助。



进一步提到,私有覆盖虚拟成员将阻止进一步的类继承它。即使这有问题。修改上述程序以包括:

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

和主测试程序:

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

输出为:

  C :: func called 


解决方案

行为正确。每当你将函数声明为virtual时,你指示编译器生成一个虚拟调用,而不是直接调用这个函数。每当你覆盖后代类中的虚函数,你指定这个函数的行为(你不改变那些客户端的访问模式,谁依赖父的接口)。



更改后代类中虚拟函数的访问模式意味着您希望从直接使用后代类(依赖子的接口)的客户端中隐藏它。



考虑下面的例子:

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

process函数依赖父接口。它可以用于任何类,公共派生自A.你不能公开 - 从A(说每个B都是A),但是隐藏其接口的一部分。那些期望A必须获得完全功能的A的人。


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

解决方案

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

这篇关于公共虚拟函数派生私人在C + +的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆