考虑以下父/子对象模型。目的是让父级和子级都使用 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/