使用 C++ 智能指针构建 many-to-many/bidirectional 引用
Structuring many-to-many/bidirectional references with C++ smart pointers
我决定用 C++ 做一个项目,因为我还不知道 C++。我正在尝试尽可能多地用 C++ 做所有事情,这意味着很少有原始指针。
我 运行 遇到了如何构建我的对象集合的问题。公平警告,此描述将非常抽象。
- 只有一个 class 实例。我们称它为
Foo
- 这个
Foo
需要容纳classBar
的很多对象。要求快速插入和删除,不需要顺序,所以我想用一套。
- 每个
Bar
恰好拥有 4 个 Baz
类型的对象,这些对象在初始化时创建并固定。
- 每个
Baz
都有指向许多其他类型 Baz
的对象的指针。出于实施原因,每个 Baz
还必须引用拥有它的 Bar
。
- 给定一个现有的
Baz
对象,我需要从 Foo
的集合中删除相应的 Bar
对象并相应地释放内存。 (我有一个算法保证,在删除时,拥有 Bar
的 Baz
个对象仅指向该 Bar
拥有的其他 Baz
个对象)
我尝试实现它的方法是为 Foo 存储一组唯一的 Bar 指针,处理多对多 Baz 关系的共享指针,以及 Baz->Bar 关系的普通引用,每个 Bar 4 个目的。问题是我无法再从 Baz
对象中获取 Bar unique_ptr
。我有一个参考,但设置删除方法需要 unique_ptr
,因此不容易删除。有没有更好的方法来构造它而不必诉诸手动 pointer/memory 管理?
老实说,我认为这里不需要智能指针,因为所有对象都已由容器管理 - 因此可以确保删除它们。
所以我只使用原始指针并让容器完成它们的工作:
struct Baz
{
struct Bar& bar;
std::vector<Baz*> bazs; // no need to be smart - deleted elsewhere
Baz(Bar& bar): bar(bar) {} // don't use bar in this constructor!
};
struct Bar
{
std::array<Baz, 4> bazs;
Bar(): bazs({*this, *this, *this, *this}) {}
};
struct Foo
{
std::vector<Bar> bars;
};
只要原始指针指向的对象由智能指针或容器管理,使用原始指针就没有问题。
我在此示例中使用了 std::vector
,但您可以使用您认为合适的任何内容。我怀疑 std::vectors
可能会与 std::set
竞争,因为它们使用连续内存,这与 CPU 兑现很好。
我决定用 C++ 做一个项目,因为我还不知道 C++。我正在尝试尽可能多地用 C++ 做所有事情,这意味着很少有原始指针。
我 运行 遇到了如何构建我的对象集合的问题。公平警告,此描述将非常抽象。
- 只有一个 class 实例。我们称它为
Foo
- 这个
Foo
需要容纳classBar
的很多对象。要求快速插入和删除,不需要顺序,所以我想用一套。 - 每个
Bar
恰好拥有 4 个Baz
类型的对象,这些对象在初始化时创建并固定。 - 每个
Baz
都有指向许多其他类型Baz
的对象的指针。出于实施原因,每个Baz
还必须引用拥有它的Bar
。 - 给定一个现有的
Baz
对象,我需要从Foo
的集合中删除相应的Bar
对象并相应地释放内存。 (我有一个算法保证,在删除时,拥有Bar
的Baz
个对象仅指向该Bar
拥有的其他Baz
个对象)
我尝试实现它的方法是为 Foo 存储一组唯一的 Bar 指针,处理多对多 Baz 关系的共享指针,以及 Baz->Bar 关系的普通引用,每个 Bar 4 个目的。问题是我无法再从 Baz
对象中获取 Bar unique_ptr
。我有一个参考,但设置删除方法需要 unique_ptr
,因此不容易删除。有没有更好的方法来构造它而不必诉诸手动 pointer/memory 管理?
老实说,我认为这里不需要智能指针,因为所有对象都已由容器管理 - 因此可以确保删除它们。
所以我只使用原始指针并让容器完成它们的工作:
struct Baz
{
struct Bar& bar;
std::vector<Baz*> bazs; // no need to be smart - deleted elsewhere
Baz(Bar& bar): bar(bar) {} // don't use bar in this constructor!
};
struct Bar
{
std::array<Baz, 4> bazs;
Bar(): bazs({*this, *this, *this, *this}) {}
};
struct Foo
{
std::vector<Bar> bars;
};
只要原始指针指向的对象由智能指针或容器管理,使用原始指针就没有问题。
我在此示例中使用了 std::vector
,但您可以使用您认为合适的任何内容。我怀疑 std::vectors
可能会与 std::set
竞争,因为它们使用连续内存,这与 CPU 兑现很好。