是否建议明确地使重写功能虚拟?
在C ++ 11之前,在派生类中重写虚拟函数之前,建议将virtual关键字也添加到派生类函数中,以使意图清晰。
现在这样的功能被标记为“覆盖”,其中包括必须有虚拟基本功能的概念。 因此,我现在宁愿忽略虚拟:
class Derived: public Base {
public:
void Overriden() override;
// Instead of: virtual void Overriden() override;
};
但是,这会导致MSVC 2012中出现智能感知错误:“覆盖”修饰符需要虚拟函数声明并带有明确的“虚拟”关键字
编译器显然编译这个类,但是这个错误让我想到了它。 是否仍然有充分的理由添加虚拟关键字?
我认为这更多的是品味的问题:-)
我更喜欢在定义后面写入重写,这意味着函数已经是虚拟的。 程序员是懒惰的定义,所以保持源代码简洁:-)
我们在我们的编码准则中添加了一条规则,在正常的更改过程中或在重构实际的类时,必须覆盖重写,并且应该从旧代码中删除虚拟。
但这只是我们的解决方案,没有技术上的理由!
正如在override
关键字的文档中所报告的那样,其含义是手头的函数必须覆盖一个虚函数:
在方法声明中,覆盖指定函数必须重写基类方法。
这是执行(即使编译器强制执行)这种要求的一种手段。 当然,如果基类的函数不是虚拟的,代码将不会编译。 因此,正如你所指出的那样,添加虚拟是多余的。
我认为在c ++ 11之前添加它并不是一个好建议。 考虑一下这段代码:
#include <iostream>
using namespace std;
class A{
public:
void f(){
cout << "A" << endl;
}
};
class B : public A{
public:
virtual void f(){
cout << "B" << endl;
};
};
class C : public B{
public:
void f(){
cout << "C" << endl;
};
};
int main( int argc, char* argv[] )
{
C c;
A& aref = c;
aref.f();
B& bref = c;
bref.f();
}
其输出显然是“A”,后面是“C”。 如您所见,在class C
添加virtual
根本没有任何作用,而class B
virtual
中扮演关键角色。 针对向class C
添加virtual
的惯例会使得难以一目了然。
是的,在重写基类行为时,您应该更喜欢使用override
而不是virtual
。 因为它可能导致可能的错误
这怎么可能导致错误? 这是一个例子,
#include <iostream>
using namespace std;
class Base {
public:
virtual void foo() {
std::cout << "BASE foo" << std::endl;
}
void bar() {
std::cout << "BASE bar" << std::endl;
}
};
class A : public Base{
public:
void foo() override {
std::cout << "A foo" << std::endl;
}
virtual void bar() {
std::cout << "A bar" << std::endl;
}
};
class B : public A {
public:
void bar() override {
std::cout << "B bar" << std::endl;
}
};
int main(int argc, char *argv[])
{
B b;
A *a = &b;
Base *base = &b;
base->foo();
a->foo();
base->bar();
a->bar();
return 0;
}
而输出将是
A foo
A foo
BASE bar
B bar
foo()
会被正确覆盖,但bar
在某些情况下不会被隐藏。 即使底层对象相同,对bar()
的调用也不会调用相同的方法
如果我们强制自己总是在override
时使用override
,并且只在virtual
中定义新的虚函数,那么当我们尝试void bar() override {}
,编译器会error: 'void A::bar()' marked 'override', but does not override
这正是Autosar规范定义以下规则的原因
规则A10-3-1(要求,实现,自动化)虚拟函数声明应包含三个指定符中的一个:(1)虚拟,(2)覆盖,(3)最终。
理由:指定这三个说明符中的多个以及虚拟函数声明是多余的,并且是潜在的错误来源。
链接地址: http://www.djcxy.com/p/15855.html上一篇: Is it recommended to explicitly make overriding functions virtual?
下一篇: Beginning of Project