假设我想调用我的对象的外部函数来在body构造函数中执行一些检查。由于对象的生命周期是在构造函数的主体完成执行时开始的,这是不安全的设计吗?
struct A;
void check(A const&) { /* */ }
struct A
{
A() { check(*this); }
};
我的意思是,我用一个尚未存在的对象调用和外部函数。是不确定的行为?
相关问题:如果我把那个检查函数作为成员函数(静态与否),那么该标准在构造函数之外但在类中使用非实时对象的内容是什么?
在一个类的观点和它的用户(一种在课堂上和在课堂外的生活中)之间的生命周期概念有什么不同吗?
答案 0 :(得分:8)
调用A
时,check()
的生命周期不会开始,因为来自[base.life]:
类型为
T
的对象的生命周期始于:
- 获得具有
T
类型的正确对齐和大小的存储,并且- 如果对象具有非空的初始化,则其初始化完成。
A
具有非空的初始化。从[class.base.init] / 13:
在非委托构造函数中,初始化按以下顺序进行:
- ...
- - 最后,执行构造函数体的复合语句。
然而,尽管A
尚未开始其生命周期,标准另外提供了[class.base.init] / 16:
可以为正在构造的对象调用成员函数(包括虚拟成员函数,10.3)...但是,如果这些操作是在 ctor-initializer 中执行的(或者在直接调用的函数中) 或者,在基类的所有 mem-initializers 完成之前,间接来自 ctor-initializer ,操作的结果是未定义的。
关于终身问题,之间没有区别:
void check(const A& ) { .. }
struct A {
A() { check(*this); }
};
和
struct A {
void check() const { .. }
A() { check(); }
};
明确允许后者(因为它不在 ctor-initializer 中),所以我认为没有理由在终生的基础上排除前者。