我正在使用boost :: shared_ptr在我的游戏引擎中组织我的指针数据。
我试图用一个很短的例子来说明我的问题:
class CSceneNode
{
public:
CSceneNode(CScene *p) : parent(p) {}
void foo() {
parent->notifyThatFooWasCalledOnMe(my_shared_ptr_version_of_this???);
};
CScene *parent;
};
class CScene
{
public:
void addNode() {
nodes.push_back(boost::shared_ptr<CSceneNode>(new CSceneNode(this)));
}
void notifyThatFooWasCalledOnMe(boost::shared_ptr<CSceneNode> node) {
foo_was_called[node] = true;
}
std::list<boost::shared_ptr<CSceneNode> > nodes;
std::map<boost::shared_ptr<CSceneNode>, bool> foo_was_called;
};
因此问题是: CScene创建了CSceneNode,并将boost :: shared_ptr中的这些拥有到列表中。
现在,孩子需要通知父母一项变更。这很简单,因为我将CScene的指针传递给CSceneNode,节点知道它的父节点。由于节点的寿命不会长于父节点,因此只需传递一个指针即可。
但是父母也需要知道是谁回电话,而且问题就在于此。父不知道原始指针,它只知道共享指针,所以找出哪个子进程调用的唯一方法是搜索所有节点以找到内部具有相同原始指针的那个,或者从raw创建另一个映射映射指向shared_ptr的指针。最后一个在删除节点时需要额外的维护。我也可以将shared_ptr传递给子本身以帮助它自己发送回来,但这看起来很愚蠢。
谁能告诉我该怎么做?有更好的方法吗?
答案 0 :(得分:3)
现在,孩子需要通知家长有变化。
删除此要求,整个问题崩溃......以及循环依赖。
您可以考虑使用基于事件的系统,或者进行状态轮询。
答案 1 :(得分:2)
看起来您可能想要使用enable_shared_from_this<>,这是一种让对象知道自己的shared_ptr&lt;&gt;的方法。所有权。
因此...
class CSceneNode : public boost::enable_shared_from_this<CSceneNode> // <- (1)
{
public:
CSceneNode(CScene *p) : parent(p) {}
void foo() {
parent->notifyThatFooWasCalledOnMe(shared_from_this()); // <- (2)
};
CScene *parent;
};
答案 2 :(得分:0)
如何在地图中少覆盖谓词
std::map<boost::shared_ptr<CSceneNode>, bool, MyLess>
您可以通过指针进行比较,因此要找到指针,只需要从指针创建shared_ptr的临时实例。