c++从我共享示例.一文看懂从我共享(enable_shared_from_this).
#include <memory>
#include <iostream>
struct Good: std::enable_shared_from_this<Good> // 注意:继承
{
std::shared_ptr<Good> getptr() {
return shared_from_this();//继承了一个方法,用弱针实现
}//从此共享,代表这是已生成的共享,在总计数里面不应该+1,否则引用计数不对.用弱针(未加0)实现.
};
struct Bad
{
// 错误写法:用不安全的表达式试图获得 this 的 shared_ptr 对象
std::shared_ptr<Bad> getptr() {
return std::shared_ptr<Bad>(this);//这个是应返回计数不变的共享针,如果为普通共享针的话,则析构出问题,因为已是共享针,+1会出错.这里应该是保持不变的共享针,即返回共享针,但计数未变化.
}
~Bad() { std::cout << "Bad::~Bad() called\n"; }
};
int main()
{
// 正确的示例:两个 shared_ptr 对象将会共享同一对象
std::shared_ptr<Good> gp1 = std::make_shared<Good>();//1个共享针
std::shared_ptr<Good> gp2 = gp1->getptr();//还是这1个共享针,gp2与gp1是完全相同的.这个共享针是假的共享针.未加引用计数的.如果等号右边是上一行这样的,才是真正的共享针.这里的gp2不过是相当于复制了一份gp1罢了.一个重复利用的假的共享针.
std::cout << "gp2.use_count() = " << gp2.use_count() << '\n';//打印出来的是有几个共享针指向本地对象.这只是表面的肤浅的共享针个数(可指向不同对象/相同对象针),在共享针内部,一定有一个统计真正的共享针个数,即指向不同对象针的个数.
//use_count指的是指向->当前共享针对象的共享针个数.
// 错误的使用示例:调用 shared_from_this 但其没有被 std::shared_ptr 占有
try {
Good not_so_good;//不能这样构造.从此共享,开始必须是共享针,从此共享未+1.
std::shared_ptr<Good> gp1 = not_so_good.getptr();//先不是共享针,这样获得的是未加引用计数的共享针,所以是错的.
} catch(std::bad_weak_ptr& e) {//用弱针实现的未加0共享针.
// C++17 前为未定义行为; C++17 起抛出 std::bad_weak_ptr 异常
std::cout << e.what() << '\n';
}
// 错误的示例,每个 shared_ptr 都认为自己是对象仅有的所有者
std::shared_ptr<Bad> bp1 = std::make_shared<Bad>();//1个共享针
std::shared_ptr<Bad> bp2 = bp1->getptr();//2个共享针,然而实际上只有1个对象.
std::cout << "bp2.use_count() = " << bp2.use_count() << '\n';
} // UB : Bad 对象将会被删除两次
可能的输出:
gp2.use_count() = 2
bad_weak_ptr
bp2.use_count() = 1
Bad::~Bad() called
Bad::~Bad() called
*** glibc detected *** ./test: double free or corruption
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现