我正在阅读虚拟功能,现在对覆盖虚拟功能感到困惑。 我想确认下面给出的代码是一样的吗?
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的衍生功能相同。请清除我的困惑谢谢。
答案 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虚拟关键字很重要。作为一般的经验法则,如果函数有一些虚拟方法,那么将它作为虚拟析构函数是很好的。