【问题标题】:Interaction Between Interface Implementation and Private Inheritance接口实现和私有继承之间的交互
【发布时间】:2018-05-04 16:48:51
【问题描述】:

当一个类被私有继承时,该类的所有成员在子类中变为私有。但是,在下面的示例中,我们能够通过 AD 间接访问私有继承的 doWork 函数实现(指向使用指向 R 类型的指针)。

这是怎么允许的?虚拟查找是否会忽略可见性规则,因为它是在运行时完成的?

#include <iostream>
using std::cout;

class R
{
public:
    virtual void doWork() = 0;
};

class RA : public virtual R
{
public:
    void doWork() { cout << "RA doWork\n"; };
};

class P : public virtual R, private RA
{
public:
    P() : RA() {};
};


class AD : public virtual R, private P
{
public:
    AD() : P() {};

    void doWork(int k) { cout << "AD Time dowork " << k << "\n";}
};

int main()
{
    AD ad;
    R* p = &ad;
    p->doWork();
}

上面的代码在运行时会打印“RA doWork”。我的预期是它会导致运行时错误,因为由于私有继承,doWork 的定义将无法从 p 访问。

【问题讨论】:

  • 对私有变量或类的访问是在编译时解决的,很容易被打败。 C++ 中的“私有”概念不是安全特性。
  • doWork 通过 R 公开。更改为 class AD : private virtual R, private P,这样就可以解决问题。

标签: c++ inheritance abstract-class


【解决方案1】:

AD 私下继承自 P,但公开继承自 R。这实际上意味着在R 中声明的公共方法仍可在AD 中访问,但在P 但不在R 中声明的公共方法将无法在AD 中访问。例如,如果P 看起来像:

class P : public virtual R, private RA
{
public:
    P() : RA() {};
    void doWorkP() { std::cout << "doWorkP" << std::endl; }
};

您可以通过AD 访问doWork,但不能访问doWorkP

如果您想让R 的方法在AD 中不可访问,只需从R 私下继承即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    相关资源
    最近更新 更多