You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++标准对象生命周期:嵌套对象复用存储的示例问询

对象存储被嵌套对象复用的示例(标准反例)

没问题,咱们先把你提到的C++标准basic.life章节的原文贴出来(你标注的加粗部分我原样保留):

类型为T的对象o的生命周期结束于:若T是带有non-trivial destructor([class.dtor])的类类型,则析构函数调用开始时,或对象占用的存储被释放时,或被未嵌套于o的对象复用([intro.object])时。

这里的核心逻辑是:只有当o的存储被「不嵌套于o的对象」复用时,o的生命周期才会结束。反过来,如果复用o存储的是「嵌套于o的对象」(比如o的成员子对象、基类子对象、union成员、数组元素等),那么o的生命周期不会因此终止——这就是你要找的标准所述情况的反例。

下面给两个具体的代码示例:

示例1:Union成员复用外层对象存储

Union的所有成员共享同一块内存区域,而union的成员属于外层union对象的嵌套子对象,所以用union成员复用存储时,外层对象的生命周期不受影响:

#include <iostream>

struct MyUnion {
    // 两个共享存储的成员,都是MyUnion的嵌套子对象
    int plain_val;
    struct NestedObj {
        int nested_val;
        NestedObj(int val) : nested_val(val) {}
    } nested_obj;
};

int main() {
    MyUnion o;
    // 先激活plain_val成员,使用o的存储
    o.plain_val = 42;
    std::cout << "当前活跃成员:plain_val = " << o.plain_val << std::endl;

    // 销毁plain_val(平凡类型无需显式析构),复用o的存储构造嵌套子对象nested_obj
    new (&o.nested_obj) MyUnion::NestedObj(100);
    std::cout << "当前活跃成员:nested_obj.nested_val = " << o.nested_obj.nested_val << std::endl;

    // 此时o的生命周期仍然有效,只是活跃成员切换为nested_obj
    // 最后显式销毁nested_obj
    o.nested_obj.~NestedObj();
}

在这个例子里,MyUnion对象o的存储被它的嵌套子对象nested_obj复用,但o的生命周期并没有结束——它从创建到代码结束一直是有效的MyUnion对象。

示例2:类成员存储复用外层对象的内存

我们可以在一个类的内部开辟一块存储区域,用来动态构造/销毁它的嵌套子对象,此时复用的是外层对象的存储,但外层对象的生命周期不受影响:

#include <iostream>

struct Inner {
    int data;
    Inner(int d) : data(d) { std::cout << "Inner构造,data=" << d << std::endl; }
    ~Inner() { std::cout << "Inner销毁,data=" << data << std::endl; }
};

struct Outer {
    // 这块buf属于Outer对象存储的一部分,用来存放Inner子对象
    alignas(Inner) char storage_buf[sizeof(Inner)];

    // 获取Inner子对象的指针
    Inner* get_inner() {
        return reinterpret_cast<Inner*>(storage_buf);
    }

    // 构造Outer时初始化Inner
    Outer(int init_val) {
        new (storage_buf) Inner(init_val);
    }

    // 重置Inner:销毁旧对象,复用buf构造新对象
    void reset_inner(int new_val) {
        get_inner()->~Inner();
        // 复用Outer对象的存储(buf是Outer的成员)构造新的嵌套子对象
        new (storage_buf) Inner(new_val);
    }

    // 销毁Outer时销毁Inner
    ~Outer() {
        get_inner()->~Inner();
    }
};

int main() {
    Outer o(42);
    std::cout << "当前Inner数据:" << o.get_inner()->data << std::endl;

    o.reset_inner(100);
    std::cout << "重置后Inner数据:" << o.get_inner()->data << std::endl;

    // o的生命周期直到main结束调用析构函数才终止
}

这个例子中,Outer对象o的storage_buf成员被用来反复构造Inner子对象,复用了o的存储,但因为Inner是嵌套于o的子对象,所以o的生命周期一直持续到析构函数被调用。

内容的提问来源于stack exchange,提问作者user42768

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:19:48