虚拟构造函数习语——美德或完全谬误

发布于 2024-10-07 00:08:09 字数 352 浏览 11 评论 0 原文

C++ 中的黄金法则之一是,实例的生命周期从其构造函数成功完成时开始,在其析构函数开始时结束。

从这条规则我们得出结论,在构造函数中调用虚拟方法不是一个好主意,因为可能的派生实例无效,这会导致未定义的行为。

C++ FAQ 20.8 似乎表明相反。

我的问题是:

  • 标准中定义对象相对于构造函数和析构函数调用的生命周期的确切定义是什么?
  • 此外,所谓的“虚拟构造函数 Idom”有效吗?

One of the golden rules in C++ is that the life-time of an instance begins when its constructor completes successfully and ends when its destructor begins.

From this rule we conclude that it is NOT a good idea to call virtual methods in a constructor as the possible derived instance is not valid which would lead to undefined behavior.

The Virtual Constructor Idiom as mentioned in C++ FAQ 20.8 seems to indicate the contrary.

My question is:

  • What is the exact definition in the standard for defining the life time of objects relative to calls from their constructors and destructors?
  • and furthermore is the So called "Virtual Constructor Idom" valid?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

成熟稳重的好男人 2024-10-14 00:08:09

我认为你混淆了两个独立的(如果模糊相关的)事情。

  1. 众所周知,不应从构造函数(直接或间接)调用虚函数,原因如下所述
  2. FAQ 讨论的是从虚函数调用构造函数。从某种意义上说,它与#1 相反。这个想法是根据某些现有对象的动态类型选择构造函数(即类)。

I think you're confusing two separate (if vaguely related) things.

  1. It is well-known that one shouldn't call virtual functions from constructors (directly or indirectly), for reasons discussed here.
  2. What the FAQ is talking about is calling a constructor from a virtual function. In some sense it is the opposite of #1. The idea is to choose the constructor (i.e. the class) based on the dynamic type of some existing object.
坏尐絯 2024-10-14 00:08:09

当构造函数启动时,对象作为构造函数所属类的类型存在,该对象可能处于不一致的状态(这很好,因为当前正在对象的方法之一内执行)。也就是说,实际上是从 Base 继承的 Derived 类型的对象在 Base 构造函数中被视为 Base;任何 Base::Base() 中的 this 都被视为 Base *,无论 this 对象的实际类型是什么 指向。调用虚方法就可以了。在构造函数中,将调用构造函数类的虚拟方法,而不是对象的实际类型。

您的第一个问题包含在“

虚拟构造函数的习惯用法是完全有效的。

An object exists as the type of the class the constructor belongs to when the constructor starts, the object just may be in an inconsistent state (which is fine, as execution is currently inside one of the object's methods). That is, an object that is actually of type Derived that inherits from Base is treated as a Base in Base constructors; this in any Base::Base() is treated as a Base *, no matter the actual type of the object that this points to. Calling virtual methods is fine. In a constructor, the virtual methods for the constructor's class will be called, rather than for the actual type of the object.

Your first question is covered in "Base class on the initialisation list of a derived class' copy constructor". The short answer is it's covered by § 12.7 2-3 of C++03.

The virtual constructor idiom is completely valid.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文