考虑一个用例:
Base
,你并不关心它会发生什么。Derived
类,不应该转换为Base
。一点也不。甚至不是对它的引用,对Base
的引用,换句话说,隐式绑定应该是非法的:Derived& -> Base&
。注意:Derived
类可以是可复制的,只是它的内部结构永远不应该放入常规的Base
对象中。由于可以直接禁止从Base
初始化Derived
,因此问题仍然存在,是否可以禁止编译:{{1}}。
假设Derived& -> Base& -> Base
,指针不是问题 - 只在函数调用中自动绑定。
以下是显示问题的基本示例:
static_cast
答案 0 :(得分:3)
从它公开继承是Derived类,它不应该可以转换为Base。一点也不。
从OOP设计的角度来看,这两件事情几乎是矛盾的。我不认为语言中有一种方法可以防止将派生对象视为公共基础(通过隐式转换引用的方式)。
您可以非公开地继承Base
。
这也会阻止显式转换 - 你仍然希望能够做到这一点。但只是在课堂范围之外。您可以改为提供成员来访问基本实例:
class Derived : Base
{
public:
// ...
Base& base() {
return *this;
}
};
现在,您可以通过调用Derived::base
来替换那些显式强制转换,但是在隐式转换没有的情况下仍然允许这样做。
Derived d;
Base& b = d; // (implicit) conversion fails
Base& b = d.base(); // this works
您可能还希望实现该功能的const
版本。我将把它留作练习。
答案 1 :(得分:3)
我这样做的标准方法是使用私有继承,然后用using
解除所有想要的方法,构造函数和运算符。
class Derived : private Base {
public :
using Base::Base;
using Base::some_base_method;
}
int main(){
Derived d1(2);
d1.some_base_method();
}
对于坏事和坏事,这也通过Derived的公共接口使得许多未来的基础无法增加。 它也适用于包括CRTP的模板。
答案 2 :(得分:1)
由于您没有继承替代(您明确表示您不希望将派生用作基础),我假设您继承了一个实现。在这种情况下,答案很明确:根据您的确切需要继承private
或可能protected
。这确实禁止所有此类转换到基类,同时仍让您的孩子访问基础的实现。
如果有一个或两个基本成员需要公开公开,您可以随时using
将它们放入派生类中。