"virtual"关键字在C++的基类中是可选的吗?

Is the "virtual" keyword optional in base classes in C++?

本文关键字:基类 virtual 关键字 C++      更新时间:2023-10-16

我试图理解c++中"virtual"关键字的功能-考虑这个例子:

#ifdef USE_VIRTUAL
struct a {
  virtual void say_hi() { std::cout << "hello from a" << std::endl; }
};
#else
struct a {
  void say_hi() { std::cout << "hello from a" << std::endl; }
};
#endif
struct b : public a {
  void say_hi() { std::cout << "hello from b" << std::endl; }
};
int main( int argc, char** argc )
{
  a a_obj;
  b b_obj;
  a_obj.say_hi();
  b_obj.say_hi();
}

程序输出:

hello from a
hello from b

,不管a::say_hi是否声明为virtual。因为即使没有将say_hi声明为虚函数,函数也会被正确重写,那么将其声明为虚函数的功能是什么?

您没有使用多态性。多态行为只影响指向基类的指针和引用,如下所示:

class A; class B1 : A; class B2 : A;
B1 x;
B2 y;
A  z;
A & a1 = x;  // static type A&, dynamic type B1&
A & a2 = y;  // static type A&, dynamic type B2&
A & a3 = z;  // static and dynamic type A&

现在访问a1, a2, a3的成员函数受多态性和虚调度的约束。

然而,你必须声明第一个函数在继承层次结构的顶部是虚的,即在A !在您的示例中,没有virtual,就没有多态性,您总是调用对象的相应静态类型的成员函数。要测试这一点,再添加几行:

a & bref = b_obj;
bref.say_hi();       // call b::say_hi() if virtual, a::say_hi if not
bref.a::say_hi();    // always call a::say_hi()