公共继承自基类,私有地继承自派生类

时间:2014-01-06 21:05:22

标签: c++ inheritance

奇怪的继承情况:

class Base
{
public:
  public virtual foo() = 0;
};

class A : public Base
{
public:
  public virtual foo() override;
protected:
  int bar;
};

class B : public A//something like 'public Base, protected A'
{
public:
  public virtual foo() override;
};

基本上,B可以继承A中的所有内容,但只能“看到”(并且只能转换为)Base。基本上,我想在B中使用A的一堆功能,但希望B在语义上与A不同:

B b;
Base* valid_ptr = &b;//want this to be ok
A* invalid_ptr = &b;//want this to be invalid
A& invalid_ref = b;//want this to be super invalid
A prevent(b);//want this to not be allowed to happen   

2 个答案:

答案 0 :(得分:2)

首先,只有当A派生自Base时,您的代码才会编译。如果Base对所有人都是公开的,并且A受到保护,那么唯一的方法就是不在A之间继承Base到B.

由于A不能通过B可见,因此解决方案可以

class A: public Base 
{ ... };

class B: public Base 
{
   A a;
public:
  ...
};

如果Base的两个实例存在B(一个作为B的基础,另一个来自a成员)是不可接受的,另一个方式可以通过虚拟基地:

class A: 
  public virtual Base 
{ ... };

class B:
  public virtual Base,
  protected A
{ ... };

这将使A通过B不可见(不能隐式转换为A),但只有一个Base在A和B之间是共同的。

在所有情况下,共享虚拟基础的使用是通过成员函数优势(所谓的“堆叠平行四边形图”)或通过任意数量的接口(“钻石对象”)来实现对象共享部分实现的常用习惯。 / p> OOP纯粹主义者倾向于不喜欢这些数字,但那些人是正确的C ++公民(即使没有在其他经典的OOP启发语言中找到任何表示,因为缺少多重继承!)

答案 1 :(得分:1)

我认为你正在处理Composition vs Inheritance问题。

你可能让B继承自Base并使用合成技术来利用A。

否则,对于您列出的问题,您可能会想到渲染构造函数不可访问:

class A
{
public:
    A() {};

};

class B : private A
{
public:
    B() {};
};

e.g。 (MSVC2012)

  

错误C2243:'type cast':存在从'B *'到'A *'的转换,但是   无法进入