奇怪的继承情况:
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
答案 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 *'的转换,但是 无法进入