共享指针列表的共享指针

Posted

技术标签:

【中文标题】共享指针列表的共享指针【英文标题】:Shared pointer of list with shared pointers 【发布时间】:2017-10-30 11:08:00 【问题描述】:

我正在实现大型结构(结构 A 具有结构 B,结构 B 具有结构 C 等等......)。在其中一个嵌套级别中,一个结构具有指向自身的指针。哪种解决方案更适合管理?

struct MyStruct

    //1st version
    std::shared_ptr<std::list<std::shared_ptr<MyStruct>>> myStructPrtList;
    //2nd version
    std::list<MyStruct*> *myStructPrtList;
;

我知道通过原始指针进行管理必须注意创建和删除对象。那么智能指针呢?创建这样的列表有什么危险吗?

编辑

这就是这个结构体的使用方式:

void createStruct()

    //Here will be created pointer to main struct
    std::shared_ptr<StructA> structA = fillStruct();

    //Here get everything what is needed from this struct and this struct wont be used nymore

fillStruct 函数:

std::shared_ptr<StructA> fillStruct()

    std::shared_ptr<StructA> structA = std::make_shared<StructA>();
    //Here fill whole structA
    //Somewhere create struct B included in struct A
    structA->structB = std::make_shared<StructB>();
    //Now fill struct B
    //and so on...
    //Now somewhere in nested struct create MyStruct

    //return this whole created struct
    return structA;

感谢您的回答。

【问题讨论】:

如果您不解释您打算使用的生命周期管理/要求,我认为无法回答这个问题,通过思考,您可能会回答您自己的问题。 如果对性能要求不高,我总是更喜欢第一个版本而不是第二个版本。如果可以自动为您完成,您为什么要自己管理内存。另外,您确定要使用std::list 而不是std::vector @Timo: shared_ptr 不是一个成熟的垃圾收集。它不能进行自省,不能检测循环,因此不能打破循环。 std::shared_ptr&lt;std::list&lt;T&gt;&gt; 很少是你想要的,std::list&lt;T&gt;std::list&lt;std::shared_ptr&lt;T&gt;&gt; 更常见。 【参考方案1】:

“指向你自己的指针”的大问题是,你最终可能会得到一个对象,它持有指向自身的最后一个指针。由于此对象没有其他指针,因此无法访问且无法删除。

一个稍微复杂一点的变体是两个对象持有一个指向对方的指针,但不存在指向它们的其他指针。两者中的任何一个都会删除另一个,但无法删除两者中的第一个。

我在这里不是在谈论智能指针或哑指针,问题是根本性的。如果您正在编写垃圾收集算法,您会知道这是“循环”问题。对象关系可以用图论来表达,一般这些关系是有方向的。 A 拥有 B,这通常意味着 B 确实拥有 A。但如果确实如此,那么你就有了一个循环 A->B->A。

回避该问题的一种常见方法是创建一个包含循环的第二图。你说你有一个嵌套结构。也许父级可以拥有每个MyStruct?如果没有可以作为所有者的唯一父级,则多个父级也许可以使用shared_ptr&lt;myStruct&gt; 共享所有权 - 仍然处于更高级别。

【讨论】:

以上是关于共享指针列表的共享指针的主要内容,如果未能解决你的问题,请参考以下文章

共享指针初始化器列表构造函数及其类型构造函数的更改

如何在pybind11中将共享指针列表传递给c++对象

从向量中按内存地址删除共享指针

有没有办法将共享 ptr 转换为 void 指针,然后将 void 指针转换回共享指针?

linux C++共享指针(std::shared_ptrstd::make_shared)共享对象,reset()重置共享指针,use_count()查看引用计数

linux C++共享指针(std::shared_ptrstd::make_shared)共享对象,reset()重置共享指针,use_count()查看引用计数