C ++:对象和外部函数的生命周期

时间:2015-05-20 12:47:27

标签: c++ constructor language-lawyer object-lifetime

假设我想调用我的对象的外部函数来在body构造函数中执行一些检查。由于对象的生命周期是在构造函数的主体完成执行时开始的,这是不安全的设计吗?

struct A;

void check(A const&) { /* */ }

struct A
{
    A() { check(*this); }
};

我的意思是,我用一个尚未存在的对象调用和外部函数。是不确定的行为?

相关问题:如果我把那个检查函数作为成员函数(静态与否),那么该标准在构造函数之外但在类中使用非实时对象的内容是什么?

在一个类的观点和它的用户(一种在课堂上和在课堂外的生活中)之间的生命周期概念有什么不同吗?

1 个答案:

答案 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 中),所以我认为没有理由在终生的基础上排除前者。