关于析构函数中对象生命周期的说明

Zeb*_*ish 5 c++ destructor object-lifetime

另一个问题引用了C++标准:

3.8/1 “类型 T 的对象的生命周期在以下情况下结束: — 如果 T 是具有非平凡析构函数的类类型 (12.4),则析构函数调用开始,或者 — 对象占用的存储空间被重用或释放。 ”

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

成员对象在构造函数体运行之前活跃起来,并且它们一直活跃到析构函数完成之后。因此,您可以在构造函数和析构函数中引用成员对象。

对象本身直到它自己的构造函数完成后才会活跃起来,并且一旦它的析构函数开始执行它就会死亡。但这仅就外部世界而言。构造函数和析构函数仍然可以引用成员对象。

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

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);
}

};
Run Code Online (Sandbox Code Playgroud)

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

对象本身直到它自己的构造函数完成后才会活跃起来,并且一旦它的析构函数开始执行它就会死亡。但这仅就外部世界而言。构造函数和析构函数仍然可以引用成员对象。

Adr*_*ica 3

C++ 标准对于类成员在执行过程中的确切状态似乎确实有点自相矛盾。对于析构函数执行

\n

然而,此C++ 标准草案 的以下摘录可能会让您对调用removeFromGuestList函数的调用应该是安全的(粗体斜体格式是我添加的):

\n
\n

15.7 构建和销毁

\n

1 \xc2\xa0\xc2\xa0\xc2\xa0对于具有重要构造函数的对象,在构造函数开始执行之前引用该对象的任何非静态成员或基\n类会导致\n未定义的行为。对于具有非平凡析构函数的对象,在析构函数完成执行后\n引用该对象的任何非静态成员或基类引用该对象的任何非静态成员或基类会导致未定义的行为。

\n
\n

目前尚不清楚(至少对我来说)是,一旦析构函数开始执行,通过对被销毁对象的引用来引用这些类成员是否有效。也就是说,假设您的Person班级有一个成员,ObjectType a,person.a在您的removeFromGuestList函数

\n

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

\n