我通常会发现这个片段潜入我的代码中,其中两个互不拥有的对象需要有一个指向彼此的指针,并且一旦其中一个对象被销毁,这个指针就应该被“清理”,如下所示。
struct bar;
struct foo;
struct foo
{
bar* bar_item = nullptr;
~foo();
};
struct bar
{
foo* foo_item = nullptr;
~bar()
{
if (foo_item)
{
foo_item->bar_item = nullptr;
}
}
};
foo::~foo()
{
if (bar_item)
{
bar_item->foo_item = nullptr;
}
}
int main()
{
foo obj1;
bar obj2;
obj1.bar_item = &obj2;
obj2.foo_item = &obj1;
}
这里的问题是我必须
- 删除复制构造函数/赋值并实现移动构造函数/赋值(大量样板,预计每个类至少有 5 个成员)
- 将所有对象转换为shared_ptr,并且对象之间将具有weak_ptr。(也许并不总是可行,因为我可能不拥有对象的生命周期,也迫使我使用堆)
有什么方法可以避免这种情况吗?简化吗?是否有针对特定成员的 RAII 包装器以避免实施复制/移动操作?
我曾经遇到的一个简单的例子是一个图形系统,我需要一条线来连接两个球体,该线应该有指向两个球体的指针,而球体应该有一个指向该线的指针,所有这些都属于“场景” ,但是询问有关它们的“场景”需要很长的查找,指针避免了这种查找。