首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么std::enable_shared_from_this不使用可变的std::weak_ptr?

std::enable_shared_from_this 是 C++ 标准库中的一个模板类,用于解决对象在自身析构时仍然被其他 shared_ptr 引用而导致的内存泄漏问题。它通过返回 shared_ptr 的方式,使得在对象被销毁后,其他持有该 shared_ptr 的引用能够感知到该对象已经被销毁,从而避免悬空指针的产生。

为了实现这个功能,std::enable_shared_from_this 类内部维护了一个弱引用指针(std::weak_ptr),通过 weak_ptr 可以获取到相应的 shared_ptr,以确保对象被正确管理。而为什么不直接使用可变的 std::weak_ptr,主要有以下几个原因:

  1. 可变性:可变的 std::weak_ptr 意味着可以通过其修改所指向的 shared_ptr 的指向对象。这违背了智能指针的设计初衷,即将所有的资源管理操作都集中在 shared_ptr 上。可变性会导致代码的复杂性增加,增加出错的可能性。
  2. 内存安全:当一个对象在析构过程中,它的成员函数可能被调用。如果这时可变的 std::weak_ptr 能够修改 shared_ptr 的指向对象,那么就可能在对象已经销毁的情况下调用该对象的成员函数,导致内存访问错误。
  3. 一致性:std::enable_shared_from_this 的设计初衷是为了提供对象在自身析构期间仍然能够被其他 shared_ptr 引用的能力,而不是修改 shared_ptr 的指向。通过使用不可变的 std::weak_ptr,可以保持对象在生命周期内的一致性,从而更好地满足设计意图。

总结来说,std::enable_shared_from_this 类使用不可变的 std::weak_ptr 是为了保持代码的简洁性、内存安全性和一致性。它能够有效解决对象自身析构时的内存泄漏问题,同时避免了可变性带来的潜在问题。在实际应用中,可以配合使用 std::shared_ptr 和 std::weak_ptr 来实现对象的安全管理和引用计数,提高程序的可靠性和性能。

腾讯云相关产品和产品介绍链接:

  • 腾讯云 CVM(云服务器):https://cloud.tencent.com/product/cvm
  • 腾讯云云原生应用引擎 TKE(Tencent Kubernetes Engine):https://cloud.tencent.com/product/tke
  • 腾讯云云数据库 MySQL:https://cloud.tencent.com/product/cdb_mysql
  • 腾讯云云存储 COS(对象存储):https://cloud.tencent.com/product/cos
  • 腾讯云区块链服务:https://cloud.tencent.com/product/tcbs
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

如何优雅使用 std::variant 与 std::optional

:variant中值 我们可以使用std::get() 或直接std::get()来获取variant中包含值. double d = std::get(x); std::string...:variant中包含类型较多时候, 业务代码写起来会特别的费力, 标准库提供了通过std::visit来访问variant方式, 这也是大多数库对variant应用所使用方式....对比简单get方式来说, std::visit相对来说能够更好适配各个使用场合(比如ponder[一个开源C++反射库]中作为统一类型用ponder::Value对象就提供了不同种类vistor...与operator<()实现基本类似. 3.2. overloads方式访问std::variant 除了上述介绍方法, 有没有更优雅使用std::visit方式呢?...方式完成对std::variant访问, 以及相关ponde使用示例代码, 和介绍了一个利用c++17特性实现overloaded特性.

3.3K10

C++ enable_shared_from_this 具体实现

C++ 中使用 std::shared_ptr 智能指针不当有可能会造成循环引用,因为 std::shared_ptr 内部是基于引用计数来实现, 当引用计数为 0 时,就会释放内部持有的裸指针。...但是当 a 持有 b, b 也持有 a 时,相当于 a 和 b 引用计数都至少为 1,因此得不到释放,RAII 此时也无能为力。这时就需要使用 weak_ptr 来打破循环引用。...std::weak_ptr) to this....这个就是模板元编程特点,编译器生成模版函数和我们手写函数逻辑完全不同,我们手写函数不合法,编译器就会报错,但是如果编译器生成出来发现不合法,编译器就会生成这个函数。...如果生成 __enable_weak_this 函数, 那构造里调用函数,是调哪个呢?

1K30
  • 一文彻底掌握智能指针!

    这就是所谓 std::enable_shared_from_this 循环引用问题。我们在实际开发中应该避免做出这样逻辑设计,这种情形下即使使用了智能指针也会造成内存泄漏。...std::weak_ptrstd::weak_ptr 是一个控制资源生命周期智能指针,是对对象一种弱引用,只是提供了对其管理资源一个访问手段,引入它目的为协助 std::shared_ptr...expired() 方法判断了对象是否存在,为什么直接使用 std::weak_ptr 对象对引用资源进行操作呢?...sp2) //{ //} return 0; } 之所以 std::weak_ptr 增加引用资源引用计数不管理资源生命周期,是因为,即使它实现了以上说几个方法,...因此,std::weak_ptr 正确使用场景是那些资源如果可能就使用,如果不可使用则不用场景,它不参与资源生命周期管理。

    1.4K30

    C++雾中风景14:CRTP, 模板黑魔法

    1.1:std::enable_shared_from_this类 C++11 引入了一个典型CRTP类:std::enable_shared_from_this 当我们有类需要被智能指针share_ptr...这会导致指向Badthis指针被二次释放!!! 2.为什么通过继承std::enable_shared_from_this之后就没有上述问题了?...它能够规避上述问题原因如下: 通过自身维护了一个std::weak_ptr让所有从该对象派生shared_ptr都通过了std::weak_ptr构造派生。...std::shared_ptr构造函数判断出对象是std::enable_shared_from_this之类之后也会同样通过对象本身std::weak_ptr构造派生。...1.2:CRTP使用 我们重点来看看,这个CRTP在上文enable_shared_from_this之中起到了怎么样作用。从1.1代码之中我们可以看到。

    1.6K32

    C++11新特性:enable_shared_from_this解决大问题

    1 enable_shared_from_this如何使用 class MyCar:public std::enable_shared_from_this { public: shared_ptr...运行结果如下: 结果也和预期一致,通过使用std::enable_shared_from_this。两次智能指针使用增加了共享指针引用次数。程序退出时也只进行了一次析构。...从运行结果来看,使用std::enable_shared_from_this解决了:不能通过原指针增加引用次数问题。...除此之外,在使用std::enable_shared_from_this时要保证类是公有继承,至于为什么不能私有继承或者受保护继承,欢迎大家留言评论。...初始化外,还做了额外工作,既通过前面std::enable_shared_from_this继承使得后面对智能指针进行初始化时同时初始化了弱指针。

    3.9K40

    详解 C++ 11 中智能指针

    这就是所谓 std::enable_shared_from_this 循环引用问题。我们在实际开发中应该避免做出这样逻辑设计,这种情形下即使使用了智能指针也会造成内存泄漏。...std::weak_ptr std::weak_ptr 是一个控制资源生命周期智能指针,是对对象一种弱引用,只是提供了对其管理资源一个访问手段,引入它目的为协助 std::shared_ptr...() 方法判断了对象是否存在,为什么直接使用 std::weak_ptr 对象对引用资源进行操作呢?...sp2) //{ //} return 0; } 之所以 std::weak_ptr 增加引用资源引用计数不管理资源生命周期,是因为,即使它实现了以上说几个方法,调用它们也是不安全...因此,std::weak_ptr 正确使用场景是那些资源如果可能就使用,如果不可使用则不用场景,它不参与资源生命周期管理。

    2.7K31

    为什么直接使用 using namespace std 是个坏习惯

    问题 有人告诉我在代码里直接使用using namespace std;这样很不好,应该这么用,std::cout、std::cin等等。 但是为什么不好呢? 影响性能?命名冲突?...回答 这跟命名冲突有关,与性能是没有关系。...举个例子,现在考虑你正在使用两个库,分别是foo和bar, using namespace foo; using namespace bar; 不管是调用foo里函数Blah(),还是调用bar里Quux...然后有一天你库foo要升级了,里边新加了一个函数Quux(),这样就出现问题了,因为它和命名空间bar里Quux()冲突了。想一想,如果很多函数名都冲突了, 你是不是得一个一个去解决,费时费力。...因此,建议全局导入命名空间,而是你要用到哪个就显示指定哪个命名空间,这样代码本身阅读性也更好。

    31320

    灵魂拷问std::enable_shared_from_this,揭秘实现原理

    灵魂拷问std::enable_shared_from_this,揭秘实现原理 引言 在C++编程中,使用智能指针是一种安全管理对象生命周期方式。...为了解决这个问题,C++引入了std::enable_shared_from_this类,本文将深入探讨其基础知识、使用案例以及内部实现。...在可能情况下,尽量使用 std::make_shared(或 std::allocate_shared)来减少发生此错误可能性。...类初识 std::enable_shared_from_this 实现是一个类,它只包含一个 weak_ptr 字段(通常称为 _M_weak_this),这里面有很多细节:看看你知道吗?...构造函数,此时我们可以看到会调用_M_enable_shared_from_this_with,它是一个模版函数,此时会使用ADL从enable_shared_from_this类中查找enable_shared_from_this

    1.7K10

    高效使用stl::map和std::set

    1、低效率用法 // 先查找是否存在,如果不存在,则插入 if (map.find(X) == map::end()) // 需要find一次 {     map.insert(x); // 需要find...if (map.count(X) > 0) // 需要find一次 {     map.erase(X); // 需要find一次 } else {     // 不存在时处理 } 2、高效率用法...// 解决办法,充分利用insert和erase返回值,将find次数降为1 map::size_type num_erased = map.erase(X); // 需要find一次 if (0...== num_erased) {     // 不存在时处理 } else {     // 存在且删除后处理 } pair result_inserted; result_inserted = map.insert...(X); if (result_inserted.second) {     // 不存在,插入成功后处理 } else {     // 已经存在,插入失败后处理     result_inserted.first

    2.9K20

    Chapter 4: Smart Pointers

    Use std::unique_ptr for exclusive-ownership resource management 默认情况下(传入自定义析构器时), std::unique_ptr 和原始指针大小一样...> vpw{pw1, pw2}; 自定义析构器可以是函数指针,函数对象, lambda 表达式,但是 std::shared_ptr 大小仍然不变,为什么?...,并且在使用 this 构造 std::shared_ptr 地方使用 shared_from_this ()函数代替 this class Widget: public std::enable_shared_from_this...();- 另一种形式是:使用 **std::weak_ptr** 作为 **std::shared_ptr** 构造函数参数,如果 **std::weak_ptr** 已经 **expired** ,...,当 A 被销毁时, B 能检测到指向 A 指针已经悬空了,而且能够正确释放 A 内存 std::weak_ptrstd::shared_ptr 大小一样,它们使用相同控制块和操作,区别仅仅在于

    1.6K20

    C++ 新特性学习(一) -- 概述+智能指针(smart_ptr)

    } * 其中“->return_type ”是可选,仅当要指定返回值时候使用 */ int count = 0, sum = 0; std::sort(vec.begin...这段代码支持GNU-C++、VC++,如果电脑里C++版本不够则会导入BOOST里智能指针库,这时候要安装BOOST库,贴完这一段,就可以使用神奇std::shared_point了。...另外智能指针上还有个重要东西叫std::weak_ptr,这是智能指针一个监视器,内部不会改变引用技术,但是可以用于获取智能指针,当资源正常时lock函数会返回智能指针,当资源被释放了后会产生空指针...但是某些情况下我们需要返回自己智能指针怎么办呢,又有个新玩意,std::enable_shared_from_this ,只要继承它,就有一个成员方法shared_from_this用于返回自身智能指针...其内部使用一个weak_ptr维护,这就是weak_ptr一个重要使用了。

    56510

    C++ 新特性学习(一) -- 概述+智能指针(smart_ptr)

    } * 其中“->return_type ”是可选,仅当要指定返回值时候使用 */ int count = 0, sum = 0; std::sort(vec.begin...这段代码支持GNU-C++、VC++,如果电脑里C++版本不够则会导入BOOST里智能指针库,这时候要安装BOOST库,贴完这一段,就可以使用神奇std::shared_point了。...另外智能指针上还有个重要东西叫std::weak_ptr,这是智能指针一个监视器,内部不会改变引用技术,但是可以用于获取智能指针,当资源正常时lock函数会返回智能指针,当资源被释放了后会产生空指针...但是某些情况下我们需要返回自己智能指针怎么办呢,又有个新玩意,std::enable_shared_from_this ,只要继承它,就有一个成员方法shared_from_this用于返回自身智能指针...其内部使用一个weak_ptr维护,这就是weak_ptr一个重要使用了。

    33920
    领券