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. 一,先来个表格,唠 ...
随机推荐
- 移动端html页面分享
开发APP应用比开发移动端网页挑战小,因为APP应用只需要适配不同手机即可,而移动端网页不仅需要适配不同手机,还要适配同一部手机的不同浏览器. 移动端页面分享是一个常用的功能,需要宿主环境,可以是某A ...
- AGC027 C - ABland Yard 拓扑排序
目录 题目链接 题解 代码 题目链接 AGC027 C - ABland Yard 题解 发现有解的充要条件是有一个形为AABBAABBAABB的环 此时每一个点至少与两个不同颜色的点相连 对于初始不 ...
- 阿里P6大牛给予Java初学者的学习路线建议
Java学习这一部分是今天的重点,这一部分用来回答很多群里的朋友所问过的问题,那就是你是如何学习Java的,能不能给点建议?今天我是打算来点干货,因此咱们就不说一些学习方法和技巧了,直接来谈每个阶段要 ...
- cocosCreator 新版本的动作函数API的应用
利用触摸位置判断,点击的是屏幕的左侧还是右侧,控制主角左右移动: 见代码: InputControl:function () { var self=this; //cc.systemEvent sel ...
- lambda、map、reduce、filter函数讲解
# coding:utf-8 """ 几个特殊的函数: lambda lambda后面直接跟变量 变量后面是冒号 冒号后面是表达式,表达式计算结果就是本函数的返回值 作用 ...
- nagle算法和TCP_NODELAY
写socket发现的一个诡异现象,当时将多个小数据写操作合并成一个写操作,问题就没了.Chenshuo同学还建议我设置TCP_NODELAY,只是后来因为事情忙,也就没有再深究下去. 现在大概明白,是 ...
- 如何自动播放光盘、解决win7电脑不能播放光盘
如何设置光盘自动播放.允许光盘自动运行呢? 在使用电脑光驱播放光盘文件的时候,经常出现的一个问题是,光驱不能自动播放光盘,但是打开光盘的文件手动操作没有任何问题,这给使用造成了很多麻烦.那么,如何让光 ...
- useradd 命令的常见用法
在Linux系统中 useradd 是个很基本的命令,但是使用起来却很不直观.以至于在 Ubuntu 中居然添加了一个 adduser 命令来简化添加用户的操作.本文主要描述笔者在学习使用 usera ...
- Swift 计算三角形角度、两条边夹角
/// 计算三点之间的角度 /// /// - Parameters: /// - p1: 点1 /// - p2: 点2(也是角度所在点) /// - p3: 点3 /// - Returns: 角 ...
- Struct(二)
struct2 权威指南 这一节通过一个详细的实例来讲解Struct2框架的应用 1 下载和安装Struts 2框架 (1) 登录http://struts.apache.org/download.c ...