c++ - 在构造函数中调用虚函数

标签 c++ constructor overriding virtual-functions

假设我有两个 C++ 类:

class A
{
public:
  A() { fn(); }

  virtual void fn() { _n = 1; }
  int getn() { return _n; }

protected:
  int _n;
};

class B : public A
{
public:
  B() : A() {}

  virtual void fn() { _n = 2; }
};

如果我写下面的代码:

int main()
{
  B b;
  int n = b.getn();
}

人们可能希望将 n 设置为 2。

原来n设置为1,为什么?

最佳答案

从构造函数或析构函数调用虚函数是危险的,应尽可能避免。所有 C++ 实现都应调用在当前构造函数的层次结构级别定义的函数版本,而不是进一步调用。

C++ FAQ Lite在第 23.7 节中非常详细地介绍了这一点。我建议阅读该内容(以及常见问题解答的其余部分)以进行跟进。

摘录:

[...] In a constructor, the virtual call mechanism is disabled because overriding from derived classes hasn’t yet happened. Objects are constructed from the base up, “base before derived”.

[...]

Destruction is done “derived class before base class”, so virtual functions behave as in constructors: Only the local definitions are used – and no calls are made to overriding functions to avoid touching the (now destroyed) derived class part of the object.

编辑 更正了大多数(感谢 litb)

关于c++ - 在构造函数中调用虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49558579/

相关文章:

c++ - 代码 `[&]()` 在 C++ 中意味着什么?

javascript - 简单的 JavaScript 对象构造函数

java - 如何区分子类函数实现、@Override 注解和 "overloading"函数的概念?

C++ 字符串覆盖链接错误

c++ - 在 C/C++ 中创建 Windows NTFS 目录连接时出现问题

c++ - Catch2 cmake函数 'catch_discover_tests()'在构建时不起作用

c++ - NetBeans配置

java - 如何让基类知道子类创建了哪些对象?

c++ - 不调用采用 Base& 的构造函数

在 ios7 中覆盖 drawRect 失败