如果存在任何循环关系,我应该假设弱指针使用吗?
Should I assume weak pointer usage if there is any cyclic relationship?
假设我有一个Person
类,name
、age
和bestFriend
作为属性。我对如何最好地代表bestFriend
感到困惑.多个Person
实例可以指向同一个bestFriend
,这排除了unique_ptr
。并且还有循环关系的可能性,排除了shared_ptr
.那么,在这种情况下使用weak_ptr
是理想的吗?我什至想在这里使用智能指针而不仅仅是原始指针吗?
class Person {
std::string name;
int age;
std::weak_ptr<Person> bestFriend;
};
指针(原始和智能)表示一定的所有权。因此,要选择合适的指针,您需要决定所有权。如果某物拥有一个物体,那么如果这个东西死了,那么这个物体也必须死。如果我死了,我最好的朋友必须死吗?我不这么认为。因此,我没有我最好的朋友。这排除了unique_ptr
和shared_ptr
,因为它们拥有智能指针。
所以我们有两个选择:weak_ptr
或原始指针。这取决于您将如何跟踪活着的人。
最简单的方法可能是依靠智能指针来跟踪活着的人。这意味着,你对所有人都有一些shared_ptr
存储,然后你存储weak_ptr
以指向另一个人。在这种情况下,我知道如果我有一个朋友并且weak_ptr::lock()
返回nullptr
,这意味着我的朋友已经死了。方便,但不是很灵活。例如,想象一下,当一个人去世时,你需要给一个家庭写一封信。你什么时候会这样做?亲自的析构函数?这将是多种责任的混合。在shared_ptr<Person>
的自定义删除器中?这会破坏封装,因为此自定义删除程序可能具有许多功能。
另一种方法是由专门的经理跟踪活着的人。同样,您需要一些所有人都居住的存储空间。您可以按价值或通过shared_ptr
存储它们 - 由您决定。然后存储指向这些对象的原始指针。(注意:如果将它们存储在矢量中,哪个大小是要更改的对象,则存储指向它们的原始指针不是一个好主意,因为可能会重新分配)。在这种情况下,你无法通过查看原始指针来判断我最好的朋友是否还活着。我们需要检查经理以获取此信息。这更灵活,但我会说不太安全,因为我们的系统中内置了悬空指针。
我建议不要为了这个原因而存储原始指针,而是去存储一个ID。 存储人的ID,并按ID登记人员。这个注册表将处理所有混乱,并将正确检测情况,当有人想要访问死者时,触发邮递员向亲戚发出一封信等。这也允许区分我没有最好的朋友和我最好的朋友去世的情况。weak_ptr
在这两种情况下都会返回nullptr
。
PS 如果我们shared_ptr
存储给最好的朋友,那就意味着一个人只有在他是某人最好的朋友时才会活着......如此真实,但不是在软件开发领域,对不起。
智能指针std::unique_ptr<>
和std::shared_ptr<>
用于所指向对象的唯一或共享所有权。在你的Person
的情况下,这种所有权的概念几乎没有意义,最好的朋友大概最好用一个简单的原始(观察)指针来表示:
struct Person
{
std::string name;
date_type born, died=date_type::never;
const Person *bestFriend = nullptr; // defaults to none
time_type age() const
{ died==date_type::never? date_type::today()-born : 0; }
};
话虽如此,您必须确保这些指针始终有效。为此,可以使用std::deque<Person>
存储Person
,该允许添加新的Person
,而不会使任何现有的Person
指针无效。但是,您不能删除任意Person
,而不会使指向其他Person
的指针无效,因此最好将Person
标记为死,而不是删除它(您可能有另一个所有活动Person
指针的列表)。这样做的好处是可以避免悬挂最好的朋友指针(但你会得到最好的朋友已经死了)。
警告。由于您未能提供有关class Person
预期目的的更多详细信息,因此上述建议基于一些猜测,实际上可能没有用处,具体取决于您的实际意图。
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 访问私人会员指针的假设
- 如果存在任何循环关系,我应该假设弱指针使用吗?
- 假设sqlite3_exec数据库指针不更改其值是否为保存
- 是否可以安全地假设64位指针中的16个高位(2个对我来说足够了)是未设置的
- 假设引用是作为指针传递的,这有效吗