考虑以下父/子对象模型。目的是让父母和孩子都使用shared_ptr
来管理他们的一生。父母应该保留shared_ptr
来保留其子女,孩子将保留weak_ptr
给父母。
鉴于这些对象的目的是始终由std::shared_ptr
管理,构建它们的最佳方法是什么?我提出的方法(到目前为止)感觉有点笨重:我使用工厂(朋友)函数和私有构造函数来降低指向这些对象的原始指针" escape&#的可能性34 ;.然后,孩子在ctor中创建一个shared_ptr
this
,并将其放入父母的vector
个孩子中。当ctor将原始指针返回到工厂函数时,工厂函数使用shared_from_this()
得到一个shared_ptr
,它被连接到" (即与父母的孩子矢量中的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;
};
这似乎有效,但男人,感觉笨重。还有更好的方法吗?
答案 0 :(得分:2)
我这样做:
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;
};
我删除了&#34;值&#34;样板清晰。我还尝试使用最低级别的智能指针来完成工作。我可能没有100%完美地针对您的特定用例,但您应该考虑更明确定义的生命周期/所有权语义。让一切都分享一切都是一团糟,导致缺乏清晰度......拥有明确的所有权可以使事情变得更简单。由于Parent类仍然管理每个Child的生命周期,因此不需要从Child返回Parent的花哨指针 - 原始指针将起作用,因为Child不会比Parent更长。 / p>
答案 1 :(得分:1)
鉴于您对父/子管理的不舒服分裂的描述,您可以简化如下,
class Child;
class Parent {
private:
Parent() {};
friend std::shared_ptr<Child> CreateChild(const std::shared_ptr<Parent>& parent);
std::vector<std::shared_ptr<Child>> _children;
};
class Child {
private:
Child(const std::shared_ptr<Parent>& parent) : _parent(parent) {};
friend std::shared_ptr<Child> CreateChild(const std::shared_ptr<Parent>& parent);
std::weak_ptr<Parent> _parent;
};
std::shared_ptr<Child> CreateChild(const std::shared_ptr<Parent>& parent) {
auto child = std::shared_ptr<Child>(new Child(parent));
parent->_children.push_back(child);
return child;
}
另请注意,此处没有shared_from_this
,也许您的其他目的是必要的,但管理父子关系并不是必需的。