1

我知道当你想声明一个多态函数时,你必须声明基类函数 virtual。

class Base
{
public:
    virtual void f();
};

我的问题是您是否需要将继承类函数声明为虚拟,即使预期 Child 的行为就像它被“密封”一样?

class Child : public Base
{
public:
    void f();
};
4

3 回答 3

7

不,您不需要重新声明虚拟功能。

基类中的virtual函数将自动将所有覆盖函数声明为虚拟函数:

struct A
{
   void foo();          //not virtual
};
struct B : A
{
   virtual void foo();  //virtual
}
struct C : B
{
   void foo();          //virtual
}
于 2012-04-20T20:38:48.757 回答
0

在 Child 中将 f() 声明为 virtual 有助于某些人阅读 Child 的定义。它作为文档很有用。

于 2012-04-20T21:15:09.447 回答
0

一旦基类覆盖被标记为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要密封的每个类创建一个类型,或者使用不能提供完美密封的通用方法(它可能被篡改)

于 2012-04-20T21:31:40.513 回答