gpt4 book ai didi

c++ - 替换子对象的存储期限

转载 作者:行者123 更新时间:2023-12-03 07:02:44 25 4
gpt4 key购买 nike

关于下面的代码

int main()
{
struct S { int i; } s { 42 };
new (&s.i) int { 43 };
}

[basic.stc]/2

The dynamic storage duration is associated with objects created by a new-expression.



There is similar question同意新放置的位置将创建具有动态存储持续时间的对象。因为没有其他措辞可以适用于该问题中的示例。

这是一个精心设计的示例,其中有措辞说出一些有趣的东西。 [basic.stc.inherit]/1说:

The storage duration of subobjects and reference members is that of their complete object



[intro.object]/2保证创建的 int对象是 s的子对象:

If an object is created in storage associated with a member subobject or array element e (which may or may not be within its lifetime), the created object is a subobject of e's containing object if:
(requirements are satisfied, I won't copy them here)



那么,新创建的 int对象具有哪个存储期限?动态还是自动?

最佳答案

这个问题很有趣。的确,有关动态存储持续时间和new表达式的措辞不排除新的放置位置。

该表述含糊不清是由需要处理的多种情况引起的:

int main()
{
struct Simple { int i; } s { 42 };
new (&s.i) int { 43 }; // the lifecyle of the newly created object
// will auto, since Simple will be destroyed when
// going out of scope
struct Complex { char s[256]; } c;
Simple *p = new (&c.s) Simple; // the lifecycle of the newly created object
// is dynamic. You'll need to delete it in time.
// because compiler doesn't know about its true nature
// and memory will be lost when going out of scope
}

幸运的是,该标准足够精确,因此,如果您提供正确的代码(即没有UB),则每个编译器都会产生相同的结果。

实际上,动态创建对象(放置新对象)并不一定意味着对象生命周期与创建对象的范围无关。但是,您需要确保在适当的时候销毁对象,因此将其视为动态存储持续时间。

这里的关键是分配。只有内存分配才能使对象持续时间真正独立于创建对象的范围。这是在标准中表达的,但可能不尽如人意。让我们从 basic.stc/2 中的full子句开始:

Static, thread, and automatic storage durations are associated with objects introduced by declarations and implicitly created by the implementation. The dynamic storage duration is associated with objects created by a new-expression.



在这里,我将理解,只有在第一句尚未涵盖该对象的情况下,最后一句才适用。但这是目前的个人解释。因此,唯一可以确定的是,如果出现重叠,则需要格外小心。

因此,让我们更仔细地看看 动态存储持续时间[basic.stc.dynamic] / 1

Objects can be created dynamically during program execution (...). A C++ implementation provides access to, and management of, dynamic storage via the global allocation functions operator new and operator new[] and the global deallocation functions operator delete and operator delete[]. [ Note: The non-allocating forms described in 21.6.2.3 do not perform allocation or deallocation. — end note ]



第二句话清楚地表明,动态存储意味着分配。接下来是一个有趣的注释,该注释恰好指向 [new.delete.placement] / 1 一章:

These functions are reserved; a C++ program may not define functions that displace the versions in the C++ standard library. The provisions of 6.7.4 do not apply to these reserved placement forms of operator new and operator delete.



6.7.4节是 basic.stc.dynamic 部分。这意味着用于新放置的特殊分配不会创建动态存储。

动态存储和动态存储持续时间不是一个事实,并且同一件事使整个内容难以表达:
  • 动态存储持续时间意味着您必须注意对象生命周期并在必要时删除
  • 动态存储意味着对存储持续时间没有限制。
  • 在动态存储(尤其是在自动存储位置)之外的其他位置创建动态存储持续时间对象需要格外小心,因为您需要确保在可用存储时将其销毁。如果仅在新放置位置中用相同类型的对象替换一个对象,则将受益于离开范围时将销毁该对象的代码。但是在任何其他情况下,您都需要保重。

  • 这是一个 online demo ,用于新放置和销毁,并查看当封闭对象超出范围时会发生什么。它使用了 Tracer类,该类将比 int更好地突出显示不同的情况(包括在调用新的展示位置之前删除先前的对象)。

    结论:我认为,在具有如此悠久的历史和如此众多的贡献者的任何标准中,都无法避免某些歧义和循环性。但是在这种情况下,您可以看到问题本身具有您最初期望的更多方面。

    关于c++ - 替换子对象的存储期限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54734809/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com