我知道当你想声明一个多态函数时,你必须声明基类函数 virtual。
class Base
{
public:
virtual void f();
};
我的问题是您是否需要将继承类函数声明为虚拟,即使预期 Child 的行为就像它被“密封”一样?
class Child : public Base
{
public:
void f();
};
我知道当你想声明一个多态函数时,你必须声明基类函数 virtual。
class Base
{
public:
virtual void f();
};
我的问题是您是否需要将继承类函数声明为虚拟,即使预期 Child 的行为就像它被“密封”一样?
class Child : public Base
{
public:
void f();
};
不,您不需要重新声明虚拟功能。
基类中的virtual
函数将自动将所有覆盖函数声明为虚拟函数:
struct A
{
void foo(); //not virtual
};
struct B : A
{
virtual void foo(); //virtual
}
struct C : B
{
void foo(); //virtual
}
在 Child 中将 f() 声明为 virtual 有助于某些人阅读 Child 的定义。它作为文档很有用。
一旦基类覆盖被标记为virtual
所有其他覆盖都隐含地如此。虽然您不需要标记该功能,因为virtual
我倾向于出于文档目的这样做。
截至最后一部分:即使预期 Child 表现得好像它被“密封”一样?,如果你想密封类,你实际上可以在 C++11 中做到这一点(这在 C++03 中通常不能完全实现),方法是创建一个密封类,如下所示:
template <typename T>
class seal {
seal() {}
friend T;
};
然后从它继承你的密封类(CRTP):
class Child : public Base, virtual seal<Child> {
// ...
};
诀窍在于,由于使用了虚拟继承,层次结构中最派生的类型必须调用虚拟基础构造函数(在这种情况下为 int seal<Child>
),但该构造函数在模板类中是私有的,并且只能Child
通过friend
声明使用。
在 C++ 中,您必须为seal
要密封的每个类创建一个类型,或者使用不能提供完美密封的通用方法(它可能被篡改)