【发布时间】:2021-09-01 13:39:55
【问题描述】:
我正在尝试创建一个 AABBTree 结构,其中每个节点都知道其父节点和子节点。
在我的AABBTreeNode 类中,父类存储为std::shared_ptr<AABBTreeNode>,子类存储为std::vector<std::weak_ptr<AABBTreeNode>>。
这样做是为了避免 Stackoverflow 帖子中指出的循环引用。
要添加一个新的孩子,我首先计算一个有效的边界框并调用以下函数:
void AABBTreeNode::AddChild(std::shared_ptr<open3d::geometry::AxisAlignedBoundingBox> partitionBound)
{
auto child = std::make_shared<AABBTreeNode>(shared_from_this(), m_Mesh, partitionBound);
m_Children.push_back(child);
}
调用此函数后,我想使用孩子 - 但是锁定函数总是返回一个空的std::shared_ptr<T>。这是调用代码(创建子代并用三角形填充它们应该递归完成):
void AABBTreeNode::AddTriangles(std::vector<Eigen::Vector3d>& centers)
{
auto center = m_Bbox->GetCenter();
for (auto& boundPoint : m_Bbox->GetBoxPoints())
{
// here is code, which calculates the minBound and maxBound for
// up to 8 Children
auto adjustedPartitionBound = std::make_shared<open3d::geometry::AxisAlignedBoundingBox>(minBound, maxBound);
AddChild(adjustedPartitionBound);
auto child = m_Children.back().lock();
if (child)
{
//this part is never reached, since child is alway empty...
child->AddTriangles(partitionCenters);
}
}
}
为什么在这种情况下child 总是为空?
我试图只包含代码的重要部分,如果缺少某些信息,请告诉我。
【问题讨论】:
-
刚刚注意到:一旦程序离开
AddChild()函数,m_Children.back().lock()就会返回一个空指针。 -
新创建节点的唯一所有者是
AddChild中的child,当该所有者死亡时,该节点就消失了。 -
我希望父母拥有自己的孩子,而不是相反。
-
@molbdnilo 正如我在下面的评论中提到的,你的意思是交换,使父成为弱指针,子成为智能指针?
-
是的,但是将这些类型视为指针通常是有问题的(我个人不喜欢术语“智能指针”,因为它们都不是)。
shared_ptr是“这个对象可以有一个或多个所有者,当没有人想要它时就消失了”,weak_ptr是“我可以成为这个的所有者,如果当我想要它”。仔细想想,“父节点没有子节点就被销毁”似乎有点奇怪,但“子节点没有父节点就被销毁”就不是那么回事了。
标签: c++ smart-pointers weak-ptr