c++11 - 我应该如何构造一个要使用 std::shared_ptr 管理的实例?

标签 c++11 shared-ptr

考虑以下父/子对象模型。目的是让父级和子级都使用 shared_ptr 来管理它们的生命周期。父级应保留一个 shared_ptr 来(保留)其子级,并且子级将为父级保留一个 weak_ptr

考虑到这些对象的目的是始终由 std::shared_ptr 管理,构建它们的最佳方法是什么?我(到目前为止)提出的方法感觉有点笨拙:我使用工厂( friend )函数和私有(private)构造函数来减少指向这些对象的原始指针“逃逸”的可能性。然后,子级在构造函数中使用 this 创建一个 shared_ptr,并将其放入父级的子级 vector 中。当构造函数将原始指针返回到工厂函数时,工厂函数使用 shared_from_this() 来获取“连接到”的 shared_ptr (即共享引用计数) with) 位于父级子级向量中的 shared_ptr

这是我到目前为止所想到的:

class Child; // Forward decl

class Parent : std::enable_shared_from_this<Parent> {
public:                
    int value() const { return _value; };
    void set_value(int newValue) { _value = newValue; };

    std::vector<std::shared_ptr<const Child>> children() const {
        // propagate const-ness to the child pointers we hand back.
        return std::vector<std::shared_ptr<const Child>>(begin(_children), end(_children));
    };

    std::vector<std::shared_ptr<Child>> children() {
        return _children;
    };

private:

    Parent(int value) : _value(value) {};

    friend class Child; // So it can add itself to the _children vector
    friend class std::shared_ptr<Parent>; // So that I don't have to inherit public from enable_shared_from_this
    friend std::shared_ptr<Parent> CreateParent(int value); // So it can call the private ctor

    std::vector<std::shared_ptr<Child>> _children;
    int _value;
};

class Child : std::enable_shared_from_this<Child>
{
public:
    int value() const { return _value; };
    void set_value(int newValue) { _value = newValue; };

private:
    Child(const std::shared_ptr<Parent>& parent, int value) : _parent(parent), _value(value) {
        std::shared_ptr<Child> sp(this); // This feels wrong, but the existence of the shared_ptr in the parent's vector of children ensures that the precondition for calling shared_from_this() is met
        parent->_children.push_back(sp);
    };

    friend std::shared_ptr<Child> CreateChild(const std::shared_ptr<Parent>& parent, int value); // So it cal call the private ctor
    friend class std::shared_ptr<Child>; // So that I don't have to inherit public from enable_shared_from_this

    std::weak_ptr<Parent> _parent;
    int _value;
};

std::shared_ptr<Parent> CreateParent(int value) {
    return std::shared_ptr<Parent>(new Parent(value));
};

std::shared_ptr<Child> CreateChild(const std::shared_ptr<Parent>& parent, int value) {
    std::shared_ptr<Child> rv = (new Child(parent, value))->shared_from_this();
    return rv;
};

这似乎有效,但是伙计,这感觉很笨重吗?有更好的办法吗?

最佳答案

我会这样做:

class Child;

class Parent {
public:
    std::vector<const Child*> children() const {
        // propagate const-ness to the child pointers we hand back.
        // ...
    }

    const std::vector<std::unique_ptr<Child>>& children() {
        return _children;
    }

    std::shared_ptr<Parent> create() {
        // I'd rather use std::make_shared() here but it needs public ctor
        return std::shared_ptr<Parent>(new Parent());
    }

    std::unique_ptr<Child>& createChild() {
        _children.emplace_back(new Child(this));
        return _children.back();
    }

private:    
    Parent();

    std::vector<std::unique_ptr<Child>> _children;
};

class Child
{
private:
    Child(Parent* parent) : _parent(parent) {}

    friend class Parent;

    Parent* _parent;
};

为了清楚起见,我删除了“值”样板。我还尝试使用最低复杂程度的智能指针来完成工作。对于您的特定用例,我可能没有 100% 完美,但您应该考虑更明确定义的生命周期/所有权语义。让所有东西共享一切有点困惑,并导致缺乏清晰度……拥有明确的所有权可以让事情变得更简单。而且由于 Parent 类仍然管理每个 Child 的生命周期,因此不需要从 Child 回到 Parent 的花哨指针 - 原始指针就可以工作,因为 Child 的生命周期不会比 Parent 长。

关于c++11 - 我应该如何构造一个要使用 std::shared_ptr 管理的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22912698/

相关文章:

c++ - 如何在构造函数的初始化列表中初始化共享指针?

boost::make_shared<T>(...) 不编译, shared_ptr<T>(new T(...)) 编译

c++ - std::arg 为实际输入返回不正确的值(使用 MSVC 编译器)

c++ - C++11 映射值的迭代器(简单透明)

c++ - 对定义的函数使用 auto

c++11 - C++ 编译器错误 : “invalid declarator before”

c++ - 如何静态断言 std::array 类成员在 c++11 中进行排序?

c++ - first catch 捕获任何类型

c++ - 为什么 std::weak_ptr<> 不提供 bool 转换?

c++ - 在范围内保持 shared_ptr