公开继承自基类,私下继承自派生类
Publicly inherit from base class, privately inherit from derived class
奇怪的继承情况:
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
首先,只有当A从Base派生时,代码才能编译。如果Base对所有人都是公共的,并且A受到保护,那么唯一的方法就是不通过A将Base继承给B。
由于A不能通过B观察,因此解决方案可以是
class A: public Base
{ ... };
class B: public Base
{
A a;
public:
...
};
如果在B
中存在两个Base
实例(一个作为B
的基,另一个与a
成员一起出现)是不可接受的,那么另一种方法可以是通过虚拟基:
class A:
public virtual Base
{ ... };
class B:
public virtual Base,
protected A
{ ... };
这将使A通过B不可见(不能隐式转换为A),但在A和B之间只有一个共同的碱基。
在所有情况下,共享虚拟库的使用都是一个常见的习惯用法,对象通过成员函数优势(所谓的"堆叠平行四边形继承")或通过任意数量的接口("菱形对象")共享部分实现。
OOP纯粹主义者倾向于不喜欢这些数字,但这些数字是适当的C++公民(即使在其他受OOP启发的经典语言中找不到任何表示,因为缺少多重继承!)
我认为您正在处理组合与继承的问题。
你可能让B从Base继承,并使用合成技术来利用a.
否则,对于您列出的问题,您可能会考虑使构造函数不可访问:
class A
{
public:
A() {};
};
class B : private A
{
public:
B() {};
};
例如(MSVC2012)
错误C2243:"类型转换":存在从"B*"到"A*"的转换,但无法访问
相关文章:
- 大小虚拟继承中的派生类
- 继承时如何构建派生类的变量?
- 如何使用 C++ 中的继承函数访问派生类中的局部变量
- 派生类是从基类继承 v 指针并仅使用它,还是也有自己的 v 指针?
- "std::shared_from_this"不能由其派生类继承吗?
- 继承的数据如何在派生类中放置(排列)?
- C++具有空派生类对象的继承大小
- C++ 继承:基类中重载 operator+ 的 2 次在派生类中无法正常工作
- 如何调用继承的重载运算符<<并在派生类的输出中添加更多文本?
- 在模板派生类中继承具有类型别名的构造函数
- C++继承从基类指针访问派生类中的非虚拟函数
- C++排除通过派生类中的基类继承的类
- 派生类调用使用非继承成员的继承函数
- 多重继承中的派生类的行为类似于聚合
- 在派生类中具有相同签名但继承为受保护的函数
- 继承:派生类的基类属性可访问性
- 继承派生的类构造函数
- 为C++中具有多个继承派生类的vtables的基之一调用赋值运算符
- 将抽象类(仅纯虚函数)的继承/派生限制到某个类
- 多重继承派生类:如何在不重复调用 base 的情况下重用派生函数