目前我正在努力学习如何使用智能指针。 然而,在做一些实验,我发现了以下情况的,我无法找到一个解决方案satifying:
想象一下,你有B类(子)的对象的A类是父母的一个对象,但都应该知道对方:
class A;
class B;
class A
{
public:
void addChild(std::shared_ptr<B> child)
{
children->push_back(child);
// How to do pass the pointer correctly?
// child->setParent(this); // wrong
// ^^^^
}
private:
std::list<std::shared_ptr<B>> children;
};
class B
{
public:
setParent(std::shared_ptr<A> parent)
{
this->parent = parent;
};
private:
std::shared_ptr<A> parent;
};
现在的问题是如何能够类A的对象传递std::shared_ptr
本身( this
)到其子?
有用于升压共享指针(解决方案获得一个boost::shared_ptr
为this
),但如何使用来处理这个std::
智能指针?
还有std::enable_shared_from_this
只是为了这个目的。 你继承它,你可以调用.shared_from_this()
从类里面。 你也是在这里创造循环依赖可能导致资源泄漏。 这可以通过使用来解决std::weak_ptr
。 所以,你的代码可能是这样的(假设孩子依靠父母的存在,而不是周围的其他方法):
class A;
class B;
class A
: public std::enable_shared_from_this<A>
{
public:
void addChild(std::shared_ptr<B> child)
{
children.push_back(child);
// like this
child->setParent(shared_from_this()); // ok
// ^^^^^^^^^^^^^^^^^^
}
private:
// note weak_ptr
std::list<std::weak_ptr<B>> children;
// ^^^^^^^^
};
class B
{
public:
void setParent(std::shared_ptr<A> parent)
{
this->parent = parent;
}
private:
std::shared_ptr<A> parent;
};
但是请注意,调用.shared_from_this()
要求, this
所拥有std::shared_ptr
在呼叫点。 这意味着您不能创建在栈上这样的对象了,而且一般不能调用.shared_from_this()
从构造函数或析构函数中。
你必须在你设计的几个问题,似乎从你误解智能指针的遏制。
智能指针用于声明所有权。 你被宣布双方父母所拥有的所有的孩子打破这一点,也是每个孩子拥有它的父。 这两个不可能是真的。
此外,您在返回一个弱指针getChild()
通过这样做,您声明呼叫者不应该关心的所有权。 现在,这可能是非常有限,而且还这样做,你必须确保,而任何弱指针仍持有有问题的孩子会不会被摧毁,如果你想使用智能指针,它会得到自行整理。
而最后一件事。 通常情况下,当你接受新的实体,通常应接受原始指针。 智能指针可以有自己的含义,父母之间的交换孩子,但对于一般的使用,你应该接受原始指针。