澄清析构函数中的对象生命周期

Clarification about object lifetime in destructor

Another question引用C++标准:

3.8/1 "The lifetime of an object of type T ends when: — if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or — the storage which the object occupies is reused or released."

这似乎意味着不允许从析构函数访问对象的成员。然而,这似乎是错误的,事实更像是 Kerrek SB 的回答中所解释的:

Member objects come alive before a constructor body runs, and they stay alive until after the destructor finishes. Therefore, you can refer to member objects in the constructor and the destructor.

The object itself doesn't come alive until after its own constructor finishes, and it dies as soon as its destructor starts execution. But that's only as far as the outside world is concerned. Constructors and destructors may still refer to member objects.

我想知道是否可以在析构函数中将对象的地址传递给外部 class,例如:

struct Person;
struct Organizer
{
     static void removeFromGuestList(const Person& person); // This then accesses Person members
}

struct Person
{
     ~Person() {
      // I'm about to die, I won't make it to the party
      Organizer::removeFromGuestList(*this);
}

};

这对我来说似乎没问题,因为我认为一个对象的生命周期一直持续到析构函数完成之后,但是上述答案的这一部分让我怀疑:

The object itself doesn't come alive until after its own constructor finishes, and it dies as soon as its destructor starts execution. But that's only as far as the outside world is concerned. Constructors and destructors may still refer to member objects.

关于 class 成员 在 [=33= 期间的 确切 状态,C++ 标准确实似乎有点自相矛盾] 析构函数的执行。

但是,以下摘自此 Draft C++ Standard 可能 可以保证您对 removeFromGuestList 函数的调用应该是安全的(添加了粗斜体格式由我):

15.7 Construction and destruction

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. For an object with a non-trivial destructor, referring to any non-static member or base class of the object after the destructor finishes execution results in undefined behavior.

仍然不清楚(至少对我而言)的是,一旦析构函数已开始执行。也就是说,假设您的 Person class 有一个成员 ObjectType a,指的是 removeFromGuestList 函数中的 person.a valid?

另一方面,如果您要将每个必需成员作为 'distinct object' 传递,而不是将 *this 作为参数传递,那么您 注意安全;因此,将该函数重新定义为 removeFromGuestList(const ObjectType& a)(带有可能的附加参数)将 完全 安全。