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

标签 c++ virtual keyword

我试图理解 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 是否声明为虚拟的。由于即使未将 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&

现在访问 a1a2a3 的成员函数受制于多态和虚拟分派(dispatch)。

但是,您必须在继承层次结构的顶部声明第一个函数为虚函数,即在 A 中!在您的示例中,没有 virtual,就没有多态性,您总是调用对象的相应 static 类型的成员函数。要对此进行测试,请添加另外几行:

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()

关于c++ - "virtual"关键字在 C++ 的基类中是可选的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7218763/

相关文章:

c++ - 在 C++ 程序中使用多个 .cpp 文件?

c++ - 尝试使用 C++ 中的函数填充数组

装饰器模式中的 C++ 虚拟析构函数

java - 为什么在Java中在synchronized之前使用void关键字会抛出错误,但反过来却可以正常工作?

铿锵工具。键入名称不带关键字

c++ - 完美转发,为什么析构函数被调用了两次?

automation - 是否可以使用 QTP 等软件自动化虚拟桌面上的应用程序?

c++ - 实现接口(interface)的类的析构函数在引用为接口(interface)时未调用

php - 多个关键字搜索脚本需要一些专家输入

c++ - 将 unique_ptr 传递给函数对象