智能指针的比较不仅限于地址,std::unique_ptr直接比较指针地址,而std::shared_ptr和std::weak_ptr通过std::owner_less比较是否共享同一控制块,以判断所有权身份,尤其在容器键值、缓存和观察者模式中至关重要。

在C++智能指针的世界里,比较运算远不止于简单的地址判断。当我们谈及智能指针的“所有权比较规则”时,核心在于理解它们在面对底层资源时,如何界定“相同”或“不同”的管理关系。对于
std::unique_ptr
std::shared_ptr
std::weak_ptr
C++智能指针的比较运算,尤其是涉及所有权的概念,其实是围绕着不同智能指针类型及其设计哲学展开的。
std::unique_ptr
std::unique_ptr
std::move
std::unique_ptr
==
!=
<
p1 == p2
p1.get() == p2.get()
std::shared_ptr
std::weak_ptr
立即学习“C++免费学习笔记(深入)”;
std::shared_ptr
==
!=
std::shared_ptr
==
!=
std::unique_ptr
sp1 == sp2
sp1.get() == sp2.get()
shared_ptr
所有权比较 (std::owner_less
std::owner_less
std::shared_ptr
std::weak_ptr
get()
shared_ptr
std::owner_less
std::map
std::set
std::weak_ptr
std::weak_ptr
==
!=
weak_ptr
std::owner_less
std::weak_ptr
std::shared_ptr
std::weak_ptr
std::shared_ptr
==
std::owner_less
这其实是一个非常关键的细节,也是很多初学者容易混淆的地方。在我看来,这种差异的设计是出于实用性和灵活性两方面的考虑。
std::shared_ptr
operator==
shared_ptr
shared_ptr
get()
然而,
std::owner_less
shared_ptr
struct Resource {
    int id;
    std::string name;
};
struct Member {
    int value;
};
// 假设Resource里有一个Member类型的成员
struct ComplexResource {
    int resource_id;
    Member internal_member;
};
std::shared_ptr<ComplexResource> res_ptr(new ComplexResource{1, {100}});
// 创建一个shared_ptr,它与res_ptr共享所有权,但指向的是res_ptr管理的对象的某个成员
std::shared_ptr<Member> member_ptr(res_ptr, &res_ptr->internal_member);
// 此时:
// res_ptr.get() 和 member_ptr.get() 是不同的地址
// res_ptr == member_ptr 会是 false (因为get()不同)
// 但是,它们共享同一个控制块,因为member_ptr的生命周期依赖于res_ptr
// 所以,std::owner_less()(res_ptr, member_ptr) 会是 false
// 而 !(std::owner_less()(res_ptr, member_ptr) || std::owner_less()(member_ptr, res_ptr)) 会是 true
// 这表示它们在所有权层面上是等价的。在这个例子中,
res_ptr
member_ptr
==
false
res_ptr
ComplexResource
member_ptr
internal_member
internal_member
std::owner_less
shared_ptr
weak_ptr
std::map
std::set
operator==
res_ptr
member_ptr
std::weak_ptr
std::shared_ptr
std::weak_ptr
std::shared_ptr
std::weak_ptr
在比较行为上,
std::weak_ptr
std::shared_ptr
裸指针比较 (==
!=
std::weak_ptr
==
!=
weak_ptr
shared_ptr
nullptr
shared_ptr
shared_ptr
get()
所有权比较 (std::owner_less
std::weak_ptr
std::owner_less
shared_ptr
weak_ptr
shared_ptr
weak_ptr
想象这样一个场景:你有一个缓存系统,里面存储了资源的
std::weak_ptr
lock()
weak_ptr
shared_ptr
shared_ptr
weak_ptr
weak_ptr
std::shared_ptr<int> sp1(new int(10)); std::weak_ptr<int> wp1 = sp1; std::shared_ptr<int> sp2(new int(20)); std::weak_ptr<int> wp2 = sp2; // sp1 和 wp1 共享同一个控制块 bool same_owner_sp1_wp1 = !(std::owner_less<std::shared_ptr<int>>()(sp1, wp1) || std::owner_less<std::shared_ptr<int>>()(wp1, sp1)); // true // sp1 和 wp2 不共享同一个控制块 bool same_owner_sp1_wp2 = !(std::owner_less<std::shared_ptr<int>>()(sp1, wp2) || std::owner_less<std::shared_ptr<int>>()(wp2, sp1)); // false // 让 sp1 过期,观察资源被销毁 sp1.reset(); // 此时 wp1 已经过期,但它仍然知道自己曾经观察的是哪个控制块 // 它可以和另一个 shared_ptr 进行所有权比较,看它们是否“曾经”指向同一个资源 std::shared_ptr<int> sp_new(new int(30)); bool same_owner_wp1_sp_new = !(std::owner_less<std::shared_ptr<int>>()(wp1, sp_new) || std::owner_less<std::shared_ptr<int>>()(sp_new, wp1)); // false
std::weak_ptr
std::owner_less
在实际的C++开发中,正确理解并运用智能指针的所有权比较,能够帮助我们编写出更健壮、更高效的代码,尤其是在处理资源管理和对象生命周期时。
何时使用:
作为关联容器的键 (Key in Associative Containers): 这是
std::owner_less
std::shared_ptr
std::weak_ptr
std::map
std::set
std::owner_less
std::map<std::shared_ptr<MyResource>, MyMetadata>
std::shared_ptr
operator<
owner_less
实现缓存机制 (Caching Mechanisms): 在缓存系统中,你可能希望存储
std::weak_ptr
shared_ptr
weak_ptr
std::owner_less
调试与日志 (Debugging and Logging): 当你在调试复杂的对象图或资源依赖关系时,可能需要验证两个不同的
shared_ptr
weak_ptr
std::owner_less
Observer 模式或事件系统 (Observer Pattern/Event Systems): 在一些Observer模式的实现中,Subject可能持有对Observer的
weak_ptr
lock()
weak_ptr
std::owner_less
weak_ptr
如何正确使用:
std::unique_ptr
==
!=
unique_ptr
以上就是C++智能指针比较运算 所有权比较规则的详细内容,更多请关注php中文网其它相关文章!
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号