智能指针不止是 std 给你的那坨。
没有所有权的指针语义上更清楚的是 observer_ptr (如果不需要 nullable,那直接引用,包括 & 、&& 或者 std::reference_wrapper 或者其它什么类似物)。这种做法唯一的缺陷就是罗嗦,但这是语言设计本来的问题——谁叫内建指针这种责任不明确的垃圾占用了 * 这样的更简洁的语法呢(即便 * 这种语法本来就很不咋地)?注意,如果要求是像样的而不是容易让实现偷懒的设计,原则上混淆使用目的的内建指针就不应该直接在高级语言中提供:
https://github.com/FrankHB/pl-docs/blob/master/zh-CN/why-is-pointer-awful.md 。
内建的指针因为兼容包袱永远不可能更清楚,所以和 LZ 的提法相反,就是应该能禁用就禁用,而体现不得不用和可以被其它类型取代时的区别。事实上:根本意义上只有一种情况才必须使用内建的指针——互操作,例如内联汇编需要依赖二进制兼容,或者 new 这种从核心语言特性钦定返回内建指针的情形的变通(本质上,返回内建指针仍然是个目无所有权的糟粕设计,仅仅因为 T* 是内建语法就凌驾于去任意地复用而不是提供特设的 new_ptr<T> 或者干脆直接返回现代意义的 unique_ptr<T> ,这种选择根本没什么逻辑性,而且是个后患无穷的做法;只不过当年 C++ 还没模板也没 move copy-initialization,这种垃圾设计就当历史包袱忍了算了)。使用内建指针根本不能区分不得不用内建指针和允许使用 observer_ptr 的情形,仍然削弱了目的性。
题外话,BS 是反对 observer_ptr 的:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1408r0.pdf 。不过,根本上他的理由站不住脚,一部分就是上面的原因(另一部分问题是关于语言特性历史包袱的理解和 WG21 整体对核心语言设计演进方向控制上的普遍无能)。
有所有权的情形在 unique_ptr 之前首先考虑直接传值。(至少还得清楚没法表达 __restrict 的情形下没事用指针 /引用永远是被坑的。)
shared_from_this 有的坑是因为 weak_ptr 被滥用:
https://stackoverflow.com/questions/39653239