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?
发布评论
评论(2)
我认为你混淆了两个独立的(如果模糊相关的)事情。
I think you're confusing two separate (if vaguely related) things.
当构造函数启动时,对象作为构造函数所属类的类型存在,该对象可能处于不一致的状态(这很好,因为当前正在对象的方法之一内执行)。也就是说,实际上是从 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 anyBase::Base()
is treated as aBase *
, no matter the actual type of the object thatthis
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.