【问题标题】:Adding virtual specifier in a derived class在派生类中添加虚拟说明符
【发布时间】:2017-11-15 08:10:21
【问题描述】:

考虑以下代码:

struct virtualfoo 
{
    virtualfoo{};
    virtual ~virtualfoo{};

    virtual double doStuff() = 0
};


struct realbar :  virtualfoo   
{
     realbar{};
     virtual ~realbar{};

     virtual double doStuff();
};

由于我想为realbar 实现doStuff(),因此虚拟不是强制性的。但是如果我做对了,在realbar::doStuff() 旁边放置虚拟说明符不会有什么坏处,不是吗? 使用/不使用 virtual 会有什么副作用?

【问题讨论】:

  • 您缺少doStuff() 的返回类型——但是在派生类中拥有/不拥有virtual 关键字没有副作用。通常,我觉得将其包含在内会很清楚。此外,如果您在派生类中使用 override 关键字,如果您更改基类而不是派生类,则会出现编译器错误,这会很有帮助:virtual void doStuff() override(在 realbar 类定义中)
  • 编辑:改变了返回类型 ;) ty

标签: c++ class inheritance virtual


【解决方案1】:

您是否将realbar::doStuff 显式声明为虚拟并不重要,因为virtualfoo:doStuff 是虚拟的,所以它隐含为virtual。所以没有副作用; realbar::doStuff 无论如何都会是虚拟的。例如,授予这个online C++ draft standard

10.3 虚函数

(2) 如果虚成员函数 vf 在类 Base 和 一个类 Derived,直接或间接派生自 Base,一个成员 具有相同名称的函数 vf,参数类型列表(8.3.5), cv-qualification 和 ref-qualifier(或没有相同)作为 Base::vf 被声明了,那么 Derived::vf 也是虚拟的(不管是不是这样 声明)并且它覆盖 Base::vf。 ...

【讨论】:

    【解决方案2】:

    派生类中不需要virtual关键字。但是它使代码更清晰。同样在 C++11 中引入了 override 关键字,它允许源代码清楚地指定成员函数打算覆盖基类方法。

    使用关键字override,编译器将检查基类以查看是否存在具有此确切签名的虚函数。如果没有,编译器会抛出错误。

    【讨论】:

    • 它并没有像覆盖那样让事情更清晰。如果输入错误,它可以很容易地添加一个新的虚函数。最好只使用覆盖。只需编译成功,就清楚正确了。但仍然 +1。
    • @StoryTeller 同意。但是很少有人坚持使用 C++11 之前的编译器,恕我直言,在源代码中指定 virtual 关键字有助于代码审查。
    • 我没有被卖掉。实际上,我曾经让我的一位同事拉扯他的头发,因为他不明白为什么要调用他的覆盖(OnEvent 而不是onEvent)。我仍然记得他的喊声“但我把它标记为虚拟!”。谢天谢地,代码审查发现了它。
    猜你喜欢
    • 1970-01-01
    • 2011-10-29
    • 2011-01-15
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-26
    相关资源
    最近更新 更多