0

我正在将一些旧的 C++ 代码转换为使用 shared_ptr、unique_ptr 和 weak_ptr,但我一直遇到设计问题。

我有返回新对象的“生成器”方法,以及返回指向现有对象的指针的访问器方法。乍一看,解决方案似乎很简单;为新对象返回 shared_ptr,为访问者返回 weak_ptr。

shared_ptr完全避免了悬空指针,因为如果对象被删除,它的所有共享指针和弱指针都知道它。但是我不断遇到不确定共享指针之间是否存在循环引用的情况。有很多类,其中一些相互指向;有没有可能在某个时候形成一个循环?代码非常复杂,很难分辨——新类是根据脚本文件中的指令创建的。所以我不知道 shared_ptr 是否真的在防止内存泄漏并且一直在手动删除所有对象,这似乎违背了这一点。

我考虑改用unique_ptr,因为我实际上不需要任何地方的共享所有权。(旧的 C++ 代码当然没有任何共享所有权,它只是原始指针。)但是我不能从 unique_ptr 生成weak_ptrs,所以我必须使用原始指针作为弱指针的替身。这解决了内存泄漏问题,但是当 unique_ptr 被销毁时,我可能会留下悬空指针。

所以似乎我可以有一个或另一个:防弹内存泄漏或防弹悬空指针,但不能两者兼而有之。

人们告诉我,我需要将整个程序结构保留在我的脑海中,以便我可以验证没有共享指针循环,但这似乎容易出错。毕竟,我的头只有这么大。有没有办法在只考虑本地代码的情况下实现内存安全?

对我来说,这是面向对象编程的核心原则,而在这种情况下,我似乎失去了它。

4

1 回答 1

2

一个可能对您有用的策略是确保所有托管对象中的所有共享指针都是const.

由于 const shared_ptr 字段只能在构造时分配,这确保了对象只能保存指向在它们之前创建的对象的共享指针。(好吧,有办法解决这个问题,但你不会错误地这样做)

由于“之前创建”是一个总排序,这确保了共享指针的图是非循环的。

于 2018-01-20T21:10:45.950 回答