如何给 child 一个指向 parent 的弱指针? (C++)
How to give a child a weak pointer to a parent? (C++)
我读过 here,在某些 parent object 唯一拥有几个 children 的情况下,每个 child 需要能够访问它的 parent,应该使用弱指针作为 back-pointer 而不是共享指针,以避免依赖循环。
我有两个问题:
- 与简单引用相比,给 parent 一个弱指针有什么好处?
- 在下面的代码中,我应该如何向每个 child 传递一个指向其 parent 的弱指针?我知道您可以从
std::enable_shared_from_this
继承以从 this
获取共享指针。有弱指针的等价物吗?或者别的什么?
#include <memory>
#include <vector>
class Parent;
class Child {
public:
void set_parent(std::weak_ptr<Parent> parent) {
parent_ = parent;
}
std::weak_ptr<Parent> parent_;
};
class Parent {
void add_child(std::unique_ptr<Child> child) {
// child->set_parent(???);
children_.push_back(std::move(child));
}
std::vector<std::unique_ptr<Child>> children_;
};
weak_ptr
s 来自 shared_ptr
s。如果您的 parent 节点“唯一拥有”children,那么 children cannot 有 weak_ptr
s 到他们的 parents,因为这需要它们的 shared_ptr
存在于某处。
请注意,您引用的示例并未说明项目之间关系的“唯一所有权”。
此外,只要 parents 永远不会放弃 children 的所有权给系统外的代码,就没有理由不只是有一个指向 [=23] 的常规指针=](它需要是一个指针,因为不能更改引用)。指针将始终有效(从系统外部),因为 parent 必须存在才能使 child 存在。毕竟,这就是独特所有权的含义。
你说过 parent 总是唯一拥有一个 child 但你没有指定一些东西:
- 复制一个childobject有效吗?
- 移动一个childobject有效吗?
如果您对其中任何一个的回答是肯定的,那么您必须考虑如果 child 在 parent 之间复制或移动会发生什么,因为您的 child class 不会默认情况下阻止它。所以我的建议是显式删除复制和移动构造函数和赋值运算符,或者如果你想要这种能力,那么你有责任确保如果 child 被复制和/或移动它的 parent 指针指向正确的 parent 并防止它指向无效/删除的 parent.
如果你沿着显式禁用复制和移动语义的路线走下去,那么在那种情况下我想不出有什么会阻止你使用对 parent 的引用相反。
最后,如果您确实希望 children 中的弱指针指向它们的 parent,那么您可以考虑让 parent class 扩展自:enable_shared_from_this。我认为典型的用例是当你不知道你是否会比另一个 object 长寿但在它仍然有效的情况下 object 然后你想确保它在你的时候保持活力对其进行一些操作。
请注意,如果您采用这种方法,parent object 必须存储在 shared_ptr 中。参见 shared_from_this。如果不是,那么您处于未定义的行为领域,让所有人都同意这是不好的。
编辑:我忘了说如果你可以使用 C++17,你可以直接从 parent 得到 weak_ptr 传递给 child:weak_from_this
我读过 here,在某些 parent object 唯一拥有几个 children 的情况下,每个 child 需要能够访问它的 parent,应该使用弱指针作为 back-pointer 而不是共享指针,以避免依赖循环。
我有两个问题:
- 与简单引用相比,给 parent 一个弱指针有什么好处?
- 在下面的代码中,我应该如何向每个 child 传递一个指向其 parent 的弱指针?我知道您可以从
std::enable_shared_from_this
继承以从this
获取共享指针。有弱指针的等价物吗?或者别的什么?
#include <memory>
#include <vector>
class Parent;
class Child {
public:
void set_parent(std::weak_ptr<Parent> parent) {
parent_ = parent;
}
std::weak_ptr<Parent> parent_;
};
class Parent {
void add_child(std::unique_ptr<Child> child) {
// child->set_parent(???);
children_.push_back(std::move(child));
}
std::vector<std::unique_ptr<Child>> children_;
};
weak_ptr
s 来自 shared_ptr
s。如果您的 parent 节点“唯一拥有”children,那么 children cannot 有 weak_ptr
s 到他们的 parents,因为这需要它们的 shared_ptr
存在于某处。
请注意,您引用的示例并未说明项目之间关系的“唯一所有权”。
此外,只要 parents 永远不会放弃 children 的所有权给系统外的代码,就没有理由不只是有一个指向 [=23] 的常规指针=](它需要是一个指针,因为不能更改引用)。指针将始终有效(从系统外部),因为 parent 必须存在才能使 child 存在。毕竟,这就是独特所有权的含义。
你说过 parent 总是唯一拥有一个 child 但你没有指定一些东西:
- 复制一个childobject有效吗?
- 移动一个childobject有效吗?
如果您对其中任何一个的回答是肯定的,那么您必须考虑如果 child 在 parent 之间复制或移动会发生什么,因为您的 child class 不会默认情况下阻止它。所以我的建议是显式删除复制和移动构造函数和赋值运算符,或者如果你想要这种能力,那么你有责任确保如果 child 被复制和/或移动它的 parent 指针指向正确的 parent 并防止它指向无效/删除的 parent.
如果你沿着显式禁用复制和移动语义的路线走下去,那么在那种情况下我想不出有什么会阻止你使用对 parent 的引用相反。
最后,如果您确实希望 children 中的弱指针指向它们的 parent,那么您可以考虑让 parent class 扩展自:enable_shared_from_this。我认为典型的用例是当你不知道你是否会比另一个 object 长寿但在它仍然有效的情况下 object 然后你想确保它在你的时候保持活力对其进行一些操作。
请注意,如果您采用这种方法,parent object 必须存储在 shared_ptr 中。参见 shared_from_this。如果不是,那么您处于未定义的行为领域,让所有人都同意这是不好的。
编辑:我忘了说如果你可以使用 C++17,你可以直接从 parent 得到 weak_ptr 传递给 child:weak_from_this