在构造函数中调用虚函数 [英] Calling virtual functions inside constructors

查看:46
本文介绍了在构造函数中调用虚函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有两个 C++ 类:

Suppose I have two C++ classes:

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.

One might expect that n is set to 2.

结果 n 被设置为 1.为什么?

It turns out that n is set to 1. Why?

推荐答案

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

Calling virtual functions from a constructor or destructor is dangerous and should be avoided whenever possible. All C++ implementations should call the version of the function defined at the level of the hierarchy in the current constructor and no further.

C++ FAQ Lite 部分涵盖了这一点23.7 非常详细.我建议阅读该内容(以及常见问题解答的其余部分)以进行跟进.

The C++ FAQ Lite covers this in section 23.7 in pretty good detail. I suggest reading that (and the rest of the FAQ) for a followup.

摘录:

[...] 在构造函数中,虚拟调用机制被禁用,因为尚未发生从派生类的覆盖.对象是从基础向上构造的,派生前的基础".

[...] 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.

EDIT 大部分更正(感谢 litb)

EDIT Corrected Most to All (thanks litb)

这篇关于在构造函数中调用虚函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆