gpt4 book ai didi

c++ - 在 T 的构造函数中使用 *this = T() 将 "initialize"类型为 T 的对象安全吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:31:45 25 4
gpt4 key购买 nike

构造函数 Year() 在这种情况下安全吗?

struct Year {
int year;
Year(int y) : year(y) {}
Year() { *this = Year(1970); } // *this = this->operator=(Year(1970));
};

Year y;

我认为是的,因为一旦执行流到达构造函数主体,year 就已经用 int() 初始化了。还有其他问题需要考虑吗?

不要考虑同样的技巧可能会引起麻烦的其他情况。

最佳答案

当然,this will work , 并且有效。


说明

在你的 ctor-body 运行时,所有的数据成员和基础都已经构建好了,并且:

[n3290: 12.7/4] Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2). [..]

不要混淆:

[n3290: 12.7/1] For an object with a non-trivial constructor, referring to any non-static member or base class of the object before the constructor begins execution results in undefined behavior.

(注意。“在构造函数开始之前”;此子句不适用于此处。)

12.8“Copying and moving class objects”中没有任何内容禁止在构造期间赋值。


警告

请注意,这意味着对象已经开始其“生命周期”:

[n3290: 3.8/1]: The lifetime of an object of type T begins when:

  • storage with the proper alignment and size for type T is obtained, and
  • if the object has non-trivial initialization, its initialization is complete.

以及非委托(delegate) ctor 的“初始化”的最后一步:

[n3290: 12.6.2/10]: [..] Finally, the compound-statement of the constructor body is executed.

总而言之,这意味着对象的“生命周期”直到其最派生的构造函数主体完成执行后才开始。

特别是,在对象开始其生命之前传递一个指向该对象的指针不是很有用,因为通过该指针做的几乎任何事情都会调用未定义的行为:

[n3290: 3.5/8]: Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that refers to the storage location where the object will be or was located may be used but only in limited ways. [..]

但是:

[n3290: 3.8/3]: [..] [ Note: [..] Also, the behavior of an object under construction and destruction might not be the same as the behavior of an object whose lifetime has started and not ended. 12.6.2 and 12.7 describe the behavior of objects during the construction and destruction phases. —end note ]

而且,正如我们已经探索过的,12.7 友善地通知我们,成员可能在构建的这个阶段被访问。


建议

不过,您的方法很难遵循;在确定它是否有效之前,我还必须查找上面的段落,因此它显然不完全直观。

幸运的是C++0x引入了构造函数委托(delegate),这样你就可以这样写:

struct Year {
Year() : Year(1970) {}
Year(int y) : year(y) {}

int year;
};

(唉,GCC 4.5.1 不支持这个,所以 I cannot demonstrate it to you on ideone.com。事实上,for GCC as a whole there's only a "partial patch" at time of writing。)

关于c++ - 在 T 的构造函数中使用 *this = T() 将 "initialize"类型为 T 的对象安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7086445/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com