c ++继承类的虚函数

时间:2012-04-20 20:37:56

标签: c++

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

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

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

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

3 个答案:

答案 0 :(得分:7)

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

基类中的virtual函数会自动将所有重写函数声明为虚函数:

struct A
{
   void foo();          //not virtual
};
struct B : A
{
   virtual void foo();  //virtual
}
struct C : B
{
   void foo();          //virtual
}

答案 1 :(得分:0)

在Child中将f()声明为虚拟有助于某人阅读Child的定义。它作为文档非常有用。

答案 2 :(得分:0)

一旦基类覆盖被标记为virtual,所有其他覆盖都是隐含的。虽然您不需要将该功能标记为virtual,但我倾向于将其用于文档目的。

从最后一部分开始:即使预计Child会表现得像是“密封”了吗?,如果你想密封这个类,你实际上可以通过创建一个 seal 类来完成C ++ 11(这在C ++ 03中无法完全实现):

template <typename T>
class seal {
   seal() {}
   friend T;
};

然后继承你的密封类(CRTP):

class Child : public Base, virtual seal<Child> {
// ...
};

诀窍在于,由于使用了虚拟继承,层次结构中派生类型最多的类型必须调用虚拟基础构造函数(在本例中为seal<Child>),但该构造函数在模板化类中是私有的,并且仅通过Child声明提供给friend

在C ++中,你必须为你想要密封的每个类创建一个seal类型,或者使用一个没有提供完美密封的通用方法(它可以被篡改)