C++ 智能指针五
/*
代码分析: 这是标准库的源码,我们看到在enable_shared_from_this内部保存了一个weak_ptr。shared_from_this函数就是通过这个weak_ptr得到了。
但是另外一点,我们可以看到在enable_shared_from_this的构造函数中并没有对这个weak_ptr进行初始化。
这就是为什么我们不能在构造函数调用shared_from_this()的原因,因为其内部的weak_ptr并没有初始化。所以会产生错误。 在实际的编程中如果我们需要在对象初始化中用到自己的shared_ptr。可
以单独将初始化操作放到一个独立的init函数中,这时候再调用shared_from_this()是没有问题的(但还是有点问题,下面会讲到) 熟悉weak_ptr的同学可能知道,我们在使用weak_ptr前,需要用一个shared_ptr来对其进行初始化。
对weak_ptr初始化是要能获取到当前对象的引用计数对象,而引用计数对象可以通过shared_ptr对象获取到。
当然我们同样可以用一个已经初始化过的weak_ptr来初始化另一个weak_ptr,因为已初始化的weak_ptr也可能获取到对象的引用计数。 enable_shared_from_this内部的weak_ptr是通过_Do_enable函数初始化的。
而_Do_enable函数实在shared_ptr的构造函数中调用的,这是至关重要的一个环节。
正因为如此我们在调用shared_from_this之前请确保程序已经显式地创建了shared_ptr对象,
要不然enable_shared_from_this内部的weak_ptr始终是无效。 同理在析构函数中也不能调用shared_from_this()。
在析构时,引用计数已经变为零,weak_ptr已经相当于指向的是一个无效的对象,这是不能通过此无效的weak_ptr构造shared_ptr。 */ template<class _Ty>
class enable_shared_from_this
{
// provide member functions that create shared_ptr to this
public:
typedef _Ty _EStype; shared_ptr<_Ty> shared_from_this()
{ // return shared_ptr
return (shared_ptr<_Ty>(_Wptr));
} shared_ptr<const _Ty> shared_from_this() const
{ // return shared_ptr
return (shared_ptr<const _Ty>(_Wptr));
} protected:
enable_shared_from_this()
{ // construct (do nothing)
} enable_shared_from_this(const enable_shared_from_this&)
{ // construct (do nothing)
} enable_shared_from_this& operator=(const enable_shared_from_this&)
{ // assign (do nothing)
return (*this);
} ~enable_shared_from_this()
{ // destroy (do nothing)
} private:
//友元函数
template<class _Ty1,class _Ty2>
friend void _Do_enable(_Ty1 *, enable_shared_from_this<_Ty2>*, _Ref_count_base *); mutable weak_ptr<_Ty> _Wptr;
}; template<class _Ty1,class _Ty2>
inline void _Do_enable(_Ty1 *_Ptr, enable_shared_from_this<_Ty2> *_Es, _Ref_count_base *_Refptr)
{ // reset internal weak pointer
_Es->_Wptr._Resetw(_Ptr, _Refptr);
}
/* 智能指针shared_from_this崩溃问题分析 */ #include <iostream>
#include <memory> class TestClass : public std::enable_shared_from_this<TestClass>
{
public:
TestClass()
{
}
~TestClass()
{
} void show()
{
printf("hello world .\n");
} std::shared_ptr<TestClass> getPtr()
{
return shared_from_this();
}
}; int main()
{
TestClass t;
t.getPtr(); //shared_from_this()错误 TestClass* t1(new TestClass());
t1->getPtr();//shared_from_this()错误 std::shared_ptr<TestClass> t2(new TestClass());
t2->getPtr(); //正确,已提前创建了shared_ptr
}
C++ 智能指针五的更多相关文章
- 必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱
必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱 十三.小心使用智能指针. 在前面几节已经很详细了介绍了智能指针适用方式.看起来,似乎智能指针很强大,能够很方便很安全的管理 ...
- 【C++】智能指针简述(五):解决循环引用的weak_ptr
总结一下前文内容: 1.智能指针通过RAII方法来管理指针:构造对象时,完成资源初始化;析构对象时,对资源进行清理及汕尾. 2.auto_ptr,通过“转移所有权”来防止析构一块内存多次.(如何转移? ...
- 基于C/S架构的3D对战网络游戏C++框架_05搭建系统开发环境与Boost智能指针、内存池初步了解
本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...
- c++ auto_ptr智能指针
c++ auto_ptr智能指针 该类型在头文件memory中,在程序的开通通过 #include<memory> 导入,接下来讲解该智能指针的作用和使用. 使用方法: auto_ptr& ...
- Android智能指针sp wp详解
研究Android的时候,经常会遇到sp.wp的东西,网上一搜,原来是android封装了c++中对象回收机制.说明:1. 如果一个类想使用智能指针,那么必须满足下面两个条件: a. 该类是虚基 ...
- STL模板_智能指针概念
一.智能指针1.类类型对象,在其内部封装了一个普通指针.当智能指针对象因离开作用域而被析构时,其析构函数被执行,通过其内部封装的普通指针,销毁该指针的目标对象,避免内存泄露.2.为了表现出和普通指针一 ...
- 论C++的智能指针
一.简介 参考这篇博客,并且根据<C++ Primer>中相关知识,我总结了C++关于智能指针方面的内容. 为了解决内存泄漏的问题,便出现了智能指针.STL提供的智能指针有:aut ...
- DirectX11--ComPtr智能指针
综述 DirectX11 With Windows SDK完整目录 欢迎加入QQ群: 727623616 可以一起探讨DX11,以及有什么问题也可以在这里汇报. IUnknown接口类 DirectX ...
- c/c++ 智能指针 shared_ptr 和 new结合使用
智能指针 shared_ptr 和 new结合使用 用make_shared函数初始化shared_ptr是最推荐的,但有的时候还是需要用new关键字来初始化shared_ptr. 一,先来个表格,唠 ...
随机推荐
- 从新安装SQLserver 过程中报错问题合集
1.安装SQL SERVER2008 到安装支持文件就闪退? 分析:这个是由于安装目录没有删除干净导致的,我遗漏了一个文件夹:microsoft Management console文件夹没有删除的原 ...
- BZOJ.4298.[ONTAK2015]Bajtocja(Hash 启发式合并)
题目链接 \(Description\) 给定\(d\)张无向图,每张图都有\(n\)个点.一开始,在任何一张图中都没有任何边. 接下来有\(m\)次操作,每次操作会给出\(a,b,k\),意为在第\ ...
- [POI2018]Pionek
[POI2018]Pionek 题目大意: 在无限大的二维平面的原点放置着一个棋子.你有\(n(n\le2\times10^5)\)条可用的移动指令,每条指令可以用一个二维整数向量表示.请你选取若干条 ...
- WTL中最简单的实现窗口拖动的方法(转)
目前,很多基于对话框的应用程序中对话框都是不带框架的,也就是说对话框没有标题栏.众所周知,窗口的移动都是通过鼠标拖动窗口的标题栏来实现的,那么现在应用程序中的对话框没有了标题栏,用户如何移动对话框呢? ...
- JProfiler远程监控
1. 服务端安装JProfiler(与客户端版本一致) 2. 客户端配置连接: A).session——integration wizards——New remote integration B) ...
- Spring boot设置文件上传大小限制
原文:https://blog.csdn.net/lizhangyong1989/article/details/78586421 Spring boot1.0版本的application.prope ...
- Go语言之高级篇beego框架之Controller
一.Controller 控制器 Controller等同于Django里的view,处理逻辑都是在Controller里面完成的,下面就写一个最简单的Controller.写controller的时 ...
- 关于VC预定义常量_WIN32,WIN32,_WIN64(转)
VC2012 下写 Windows 程序时,有时需要判断编译环境.在之前的文章<判断程序是否运行在 Windows x64 系统下.>里说过如何在运行期间判断系统环境,但在编译时如何判断? ...
- Linux 安装 yum
1.使用RedHat系统不能正常使用yum安装 由于RedHat没有注册,所有不能使用它自身的资源更新, 查看安装源是否安装: # rpm –qa|grep yum 卸载安装源: # rpm –e – ...
- gitlab Docker容器创建命令以及从容器中备份gitlab仓库示例
Gitlab容器启动命令: docker run -d --name gitlab --publish : --publish : --hostname gitlab-server --volume ...