虽然其他人对虚拟方法的性能等都是正确的,但我认为真正的问题是团队是否知道 C++ 中虚拟关键字的定义。
考虑这段代码,输出是什么?
#include <stdio.h>
class A
{
public:
void Foo()
{
printf("A::Foo()\n");
}
};
class B : public A
{
public:
void Foo()
{
printf("B::Foo()\n");
}
};
int main(int argc, char** argv)
{
A* a = new A();
a->Foo();
B* b = new B();
b->Foo();
A* a2 = new B();
a2->Foo();
return 0;
}
这里没有什么令人惊讶的:
A::Foo()
B::Foo()
A::Foo()
因为没有什么是虚拟的。如果在 A 和 B 类中都将 virtual 关键字添加到 Foo 的前面,我们将得到以下输出:
A::Foo()
B::Foo()
B::Foo()
几乎是每个人所期望的。
现在,您提到存在错误,因为有人忘记添加虚拟关键字。所以考虑这段代码(virtual 关键字被添加到 A,而不是 B 类)。那么输出是什么?
#include <stdio.h>
class A
{
public:
virtual void Foo()
{
printf("A::Foo()\n");
}
};
class B : public A
{
public:
void Foo()
{
printf("B::Foo()\n");
}
};
int main(int argc, char** argv)
{
A* a = new A();
a->Foo();
B* b = new B();
b->Foo();
A* a2 = new B();
a2->Foo();
return 0;
}
答:和B中加了virtual关键字一样吗?原因是 B::Foo 的签名与 A::Foo() 完全匹配,并且因为 A 的 Foo 是虚拟的,所以 B 的也是。
现在考虑 B 的 Foo 是虚拟的而 A 不是的情况。那么输出是什么?在这种情况下,输出是
A::Foo()
B::Foo()
A::Foo()
virtual 关键字在层次结构中向下工作,而不是向上工作。它永远不会使基类方法成为虚拟的。第一次在层次结构中遇到虚方法是在多态性开始时。后面的类没有办法让前面的类具有虚拟方法。
不要忘记,虚拟方法意味着这个类正在让未来的类能够覆盖/改变它的一些行为。
因此,如果您有删除 virtual 关键字的规则,它可能不会达到预期的效果。
C++ 中的 virtual 关键字是一个强大的概念。您应该确保团队中的每个成员都真正了解这个概念,以便可以按设计使用它。