在c++中存在一个对象意味着什么?

时间:2021-02-24 19:09:49

[class.dtor]/15 reads, emphasis mine:

(类。井底扭矩)/ 15读,我特别强调:

Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the destructor is invoked for an object whose lifetime has ended (3.8).

一旦为对象调用析构函数,对象就不再存在;如果对其生命周期结束的对象调用了析构函数,则该行为是未定义的(3.8)。

However, as far as I can tell, this is the only reference in the standard to an object "existing." This also seems to contrast with [basic.life], which is more specific:

然而,据我所知,这是标准中对“存在”对象的唯一引用。这似乎也与basic形成了对比。更具体的:

The lifetime of an object of type T ends when:

T类型对象的生命周期结束时:

  • if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or

    如果T是具有非平凡析构函数(12.4)的类类型,则开始析构函数调用,或

  • the storage which the object occupies is reused or released.

    对象占用的存储被重用或释放。

We have two different wordings here: "the lifetime of an object ends" and "the object no longer exists," the former only happens with a non-trivial destructor and the latter happens with any destructor. What is the significance of the difference? What is the implication of an object no longer existing?

我们在这里有两个不同的措辞:“对象的生命周期结束”和“对象不再存在”,前者只发生在非平凡的析构函数中,后者发生在任何析构函数中。差异的意义是什么?一个物体不再存在的含义是什么?

1 个解决方案

#1


1  

The quoted wording would seem to imply that a compiler could correctly insert code that returns the memory associated with an object to the heap at the beginning of its destructor. But doing that would eliminate the ability of an object to reference its own members during destruction, which is required if an object is to be able to destroy itself.

引用的措词似乎暗示编译器可以正确地插入代码,在其析构函数开始时,将与对象关联的内存返回给堆。但这样做会消除对象在销毁过程中引用其自身成员的能力,如果一个对象要能够销毁自己,这是必需的。

So I think the quoted wording is broken and should be fixed.

所以我认为引用的措辞是错误的,应该被修正。

Concerning what "lifetime" and "existence" mean, I propose that there are some different contexts, in which they mean different things:

关于“生命”和“存在”的含义,我认为有一些不同的语境,它们的意思是不同的:

Within the context of construction, lifetime and existence begin when a constructor begins. Outside that context, they begin when a constructor ends.

在构造的上下文中,生命周期和存在始于构造函数的开始。在此上下文之外,它们在构造函数结束时开始。

Within the context of destruction, lifetime and existence end when a destructor ends. Outside that context, they end when destruction begins.

在破坏的范围内,当一个析构函数结束时,生命周期和存在结束。在这种背景下,当破坏开始时,它们就结束了。

So an object may refer to its own members during construction, and potentially pass itself to functions of other objects, which may refer to the object and its members, and so on. But in general, objects (instances of classes) may not be referenced (without producing undefined behavior) until after one of their constructors has finished.

因此,一个对象可以在构建过程中引用它自己的成员,并可能将自己传递给其他对象的函数,这些对象可以引用对象及其成员,等等。但是一般来说,对象(类的实例)在它们的一个构造函数完成之后才能被引用(不产生未定义的行为)。

And an object's destructor may refer to its own members and call functions of other (existing) objects, which may refer to the object being destroyed and/or its members. But in general, an object may not be referenced after its destructor has started.

一个对象的析构函数可以引用它自己的成员并调用其他(现有的)对象的函数,这些对象可以引用被销毁的对象和/或其成员。但是通常,在对象的析构函数启动后,对象可能不会被引用。

This sort of multi-contextual definition is what makes the most sense to me, but I can see arguments being made that an object should be considered to be alive from the moment memory is allocated for it to the moment that memory is released, and I would say memory for a shallow copy should be allocated for an object when one of its constructors starts, and released when its destructor ends.

这种multi-contextual定义是最合理的方式对我来说,但我可以看到进行的参数对象应考虑活着从内存分配内存释放的时刻,我想说,记忆的浅拷贝时应该分配给一个对象的构造函数,其析构函数结束的时候和释放。

#1


1  

The quoted wording would seem to imply that a compiler could correctly insert code that returns the memory associated with an object to the heap at the beginning of its destructor. But doing that would eliminate the ability of an object to reference its own members during destruction, which is required if an object is to be able to destroy itself.

引用的措词似乎暗示编译器可以正确地插入代码,在其析构函数开始时,将与对象关联的内存返回给堆。但这样做会消除对象在销毁过程中引用其自身成员的能力,如果一个对象要能够销毁自己,这是必需的。

So I think the quoted wording is broken and should be fixed.

所以我认为引用的措辞是错误的,应该被修正。

Concerning what "lifetime" and "existence" mean, I propose that there are some different contexts, in which they mean different things:

关于“生命”和“存在”的含义,我认为有一些不同的语境,它们的意思是不同的:

Within the context of construction, lifetime and existence begin when a constructor begins. Outside that context, they begin when a constructor ends.

在构造的上下文中,生命周期和存在始于构造函数的开始。在此上下文之外,它们在构造函数结束时开始。

Within the context of destruction, lifetime and existence end when a destructor ends. Outside that context, they end when destruction begins.

在破坏的范围内,当一个析构函数结束时,生命周期和存在结束。在这种背景下,当破坏开始时,它们就结束了。

So an object may refer to its own members during construction, and potentially pass itself to functions of other objects, which may refer to the object and its members, and so on. But in general, objects (instances of classes) may not be referenced (without producing undefined behavior) until after one of their constructors has finished.

因此,一个对象可以在构建过程中引用它自己的成员,并可能将自己传递给其他对象的函数,这些对象可以引用对象及其成员,等等。但是一般来说,对象(类的实例)在它们的一个构造函数完成之后才能被引用(不产生未定义的行为)。

And an object's destructor may refer to its own members and call functions of other (existing) objects, which may refer to the object being destroyed and/or its members. But in general, an object may not be referenced after its destructor has started.

一个对象的析构函数可以引用它自己的成员并调用其他(现有的)对象的函数,这些对象可以引用被销毁的对象和/或其成员。但是通常,在对象的析构函数启动后,对象可能不会被引用。

This sort of multi-contextual definition is what makes the most sense to me, but I can see arguments being made that an object should be considered to be alive from the moment memory is allocated for it to the moment that memory is released, and I would say memory for a shallow copy should be allocated for an object when one of its constructors starts, and released when its destructor ends.

这种multi-contextual定义是最合理的方式对我来说,但我可以看到进行的参数对象应考虑活着从内存分配内存释放的时刻,我想说,记忆的浅拷贝时应该分配给一个对象的构造函数,其析构函数结束的时候和释放。