使用“virtual”关键字覆盖函数,没有它

时间:2015-07-11 07:53:42

标签: c++

我正在阅读虚拟功能,现在对覆盖虚拟功能感到困惑。 我想确认下面给出的代码是一样的吗?

class A{
public:
    virtual void fun(){ }
};
class B :public A{
public:
    void fun(){}
};

class A{
public:
    virtual void fun(){ }
};
class B :public A{
public:
    virtual void fun(){}
};

如果不相同则有什么区别?正如我所料,B的虚拟关键字功能可能与B的衍生功能相同。请清除我的困惑谢谢。

3 个答案:

答案 0 :(得分:2)

是的,它们是一样的。覆盖基类中的虚函数的任何函数都被隐式声明为虚拟。

从c ++ 14标准的最后一份工作草案开始:

  

10.3虚函数[class.virtual]
  如果虚拟成员函数vf在类Base和Derived类中声明,直接或间接从Base派生,则成员函数vf具有相同名称,参数类型列表(8.3.5声明Base :: vf的 cv-qualification 和ref-§10.3249 c ISO / IEC N4296限定符(或不存在相同的),然后Derived :: vf也是虚拟的(是否如此宣布)并覆盖(111)Base :: vf。

强调我的

正如@Mats和@ixSci指出的那样,从c ++ 11开始,使用关键字override来确保你实际上覆盖虚拟函数是一种很好的做法,而不是意外重载一个函数或覆盖一个非虚函数。 就个人而言,我的首选风格是这样,但是,B中的虚拟关键字是否会增加任何价值或者甚至会损害可读性:

class A{
public:
    virtual void fun(){ }
};

class B :public A{
public:
    virtual void fun() override {}
};

答案 1 :(得分:0)

覆盖函数上的

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/> <div id="wrapper"> <div id="item-list"> <ul class="nav nav-tabs"> <li><a href="#">tab1</a></li> <li><a href="#">tab2</a></li> <li><a href="#">tab3</a></li> <li class="pull-right"><a href="#">tab4</a></li> </ul> <div ng-show="activeTab != 'create'"> <ul class="list-group"> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> <li>Some item...</li> </ul> </div> </div> </div>关键字完全没用。除了可读性之外,它没有提供任何东西(有些人可能会说它损害了可读性),但它是C ++ 03中向类读者传达函数实际上是虚拟的唯一方法,而不检查基类。

现在最好使用专门用于覆盖的关键字 - virtual。所以你的例子看起来像:

override

它不仅传达了意图,而且还确保在覆盖虚拟功能时不会犯任何错误。

答案 2 :(得分:0)

虚拟关键字告诉编译器稍后可以通过继承类(纯虚拟)来实现该功能。此外,在c ++ 11中,如果在继承类中实现的方法超出了基类的虚方法,则会检查关键字覆盖。在实现功能的情况下,没有太大的区别。我们可以认为,在虚拟的情况下,我们在其他情况下谈论关于基本方法的隐藏的avout覆盖(在这两种情况下你的cab仍然调用base的实现)。此外,这是程序员的信息,该功能旨在覆盖。在析构函数的情况下,Additionaly虚拟关键字很重要。作为一般的经验法则,如果函数有一些虚拟方法,那么将它作为虚拟析构函数是很好的。