接口实现和私有继承之间的交互

Posted

技术标签:

【中文标题】接口实现和私有继承之间的交互【英文标题】: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,这样就可以解决问题。 【参考方案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 私下继承即可。

【讨论】:

以上是关于接口实现和私有继承之间的交互的主要内容,如果未能解决你的问题,请参考以下文章

Java中接口与接口和类之间的关系

接口和抽象类的区别。

2.抽象类和接口的区别

java中抽象类和接口的区别?

2017.4.12 java中抽象类和接口的区别

Java中的接口