C++11实现模板手柄:委托构造函数、defaultkeyword分析
C++11。使用委托构造函数。和高速变量初始化,defaultkeyword重新声明默认构造函数,回答pod状态。
分析与推荐的方法。
到目前为止,VS2012和2013异常声明兼容还是停留在通信代码级,查,出现例如以下错误可忽略。
warning C4290: 忽略 C++ 异常规范,但指示函数不是 __declspec(nothrow)
下为:VS2012不支持托付构造函数。建议使用cocos2d-x 3.2及版本号的朋友更新VS至2013版。
1>d:\cpp_lab\testqueue_16th_2\testqueue_16th_2\handle.hpp(9): error C2614: “Handle<T>”: 非法的成员初始化:“Handle<int>”不是基或成员
同一时候VS2012也不支持高速初始化变量。
VS2013同一时候完毕了对于default声明。可是假设考虑和委派构造函数一起使用的话,则会有例如以下的错误:
- Handle() = default:Handle(p,new std::size_t(1)){};
- 1>d:\cpp_2013\testqueue_16th_2\testqueue_16th_2\handle.hpp(7): error C2143: 语法错误 : 缺少“;”(在“:”的前面)
编译时出现语义上的二义性。要又一次定义=():()形式的语义?
原因在:一旦使用defaultkeyword去重定义默认的构造函数使其回复至pod状态,要记得不能定义函数体,默认构造函数是由编译器合成的。
若定义了default构造函数的函数体,则会出现重载定义无法识别的编译报错。
VS2013版源代码例如以下:
- class Handle
- {
- public:
- <span> Handle() = default; // 不能声明函数体</span>
- Handle(T *p = nullptr):Handle(p,new std::size_t(1))
- {
- }
- Handle(const Handle & h):Handle(h.m_pPtr,h.m_pUseCount)//托付构造函数,将先调用目标构造函数,再完毕初始化
- {
- }
- Handle & operator = (const Handle & other);
- T & operator *() throw (std::runtime_error);
- T * operator ->() throw (std::runtime_error);
- T & operator *() const throw (std::runtime_error);
- T * operator ->() const throw (std::runtime_error);
- ~Handle(void)
- {
- rem_ref();
- }
- private:
- Handle(T*p,size_t * use):m_pPtr(p),m_pUseCount(use) // 目标构造函数
- {
- if (m_pPtr==nullptr)
- {
- delete m_pUseCount;
- m_pUseCount = nullptr;
- }
- <span style="font-family: Arial, Helvetica, sans-serif;"><span> </span>else</span>
- <span style="font-family: Arial, Helvetica, sans-serif;"><span> </span>{</span>
- <span style="font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-family: Arial, Helvetica, sans-serif;">++(*m_pUseCount);</span>
- </pre><pre name="code" class="cpp"><span style="font-family: Arial, Helvetica, sans-serif;"><span> </span>}</span>
- };
- void rem_ref()
- {
- if (--*m_pUseCount == 0)
- {
- delete m_pPtr;
- delete m_pUseCount;
- m_pPtr = nullptr;
- m_pUseCount = nullptr;
- }
- }
- private:
- T * m_pPtr = nullptr;//实际上这个赋值没太多意思
- <span> </span>size_t * m_pUseCount = nullptr;
- };
- template <typename T>
- Handle<T> & Handle<T>::operator = (const Handle<T> & other)
- {
- ++other.m_pUseCount;
- rem_ref();
- m_pPtr = other.m_pPtr;
- m_pUseCount = other.m_pUseCount;
- return *this;
- }
- template <typename T>
- inline T & Handle<T>::operator *()
- {
- if (m_pPtr!=nullptr)
- {
- return *m_pPtr;
- }
- else
- {
- throw std::runtime_error("dereference of unbound Handle");
- }
- }
- template <typename T>
- inline T * Handle<T>::operator ->()
- {
- if (m_pPtr!=nullptr)
- {
- return m_pPtr;
- }
- else
- {
- throw std::runtime_error("dereference of unbound Handle");
- }
- }
- template <typename T>
- inline T & Handle<T>::operator *() const
- {
- if (m_pPtr!=nullptr)
- {
- return *m_pPtr;
- }
- else
- {
- throw std::runtime_error("dereference of unbound Handle");
- }
- }
- template <typename T>
- inline T * Handle<T>::operator ->() const
- {
- if (m_pPtr!=nullptr)
- {
- return m_pPtr;
- }
- else
- {
- throw std::runtime_error("dereference of unbound Handle");
- }
- }
main函数:
- int*p = new int(100);
- Handle<int> pInt(p);
- Handle<int> pInt2 = Handle<int>(pInt);
- Handle<int> pInt3 = pInt2;
- try
- {
- cout << *pInt << "\t" << *pInt2 << "\t" << *pInt3 << endl;
- }
- catch (runtime_error e)
- {
- cerr<<e.what()<<endl;
- }
- try
- {
- *pInt3 = 200;
- cout << *pInt << "\t" << *pInt2 << "\t" << *pInt3 << endl;
- }
- catch (runtime_error e)
- {
- cerr << e.what() << endl;
- }
- int i = 0;
- try
- {
- pInt.~Handle();
- cout << ++i << "\t" << *pInt << "\t" << *pInt2 << "\t" << *pInt3 << endl;
- pInt.~Handle();
- cout << ++i << "\t" << *pInt << "\t" << *pInt2 << "\t" << *pInt3 << endl;
- }
- catch (runtime_error e)
- {
- cerr << e.what() << endl;
- }
- try
- {
- pInt.~Handle();
- cout << ++i<< "\t" << *pInt << "\t" << *pInt2 << "\t" << *pInt3 << ends; /*运行了前面的++操作,可是出现异常。异常销毁仅仅会析构和处理变量。不会回滚操作*/
- }
- catch (runtime_error e)
- {
- cerr << i << "\t"<< e.what() << endl;
- }
委派构造函数的使用在于内部能定义一个完整版本号的构造函数,然后在类对象未完毕初始化时调用该构造函数,先在当前地址完毕构造。这个思维应该是曾经this为很量时代(事实上我没用过很量指针形式的this)的使用方法,后来新标准定义this仅仅能为const类型,融合当前代码时长出现大量的构造函数。思考出的解决方式,不算是语法上的突破或革新。
程序结果:
版权声明:本文博主原创文章。博客,未经同意不得转载。
C++11实现模板手柄:委托构造函数、defaultkeyword分析的更多相关文章
- 委托构造函数(c++11)
1.概念 1)委托构造函数也是构造函数,它也有形参列表,它将实参传递给其他的构造函数来初始化类对象,像是把自己的一些(或者全部)构造职责委托给其他构造函数一样
- 编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异
编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异 题目挺绕口的.C++ 11的好东西不算太多,但变参模板(Variadic Template)肯定是其中耀眼的一 ...
- c++11 函数模板的默认模板参数
c++11 函数模板的默认模板参数 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> ...
- 【C/C++开发】C++11的模板类型判断——std::is_same和std::decay
C++11的模板类型判断--std::is_same和std::decay 问题提出:有一个模板函数,函数在处理int型和double型时需要进行特殊的处理,那么怎么在编译期知道传入的参数的数据类型是 ...
- 【转】第4篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:委托回调方法分析
作者: 牛A与牛C之间 时间: 2013-11-18 分类: 技术文章 | 暂无评论 | 编辑文章 主页 » 技术文章 » 第4篇:Xilium CefGlue 关于 CLR Object 与 JS ...
- 【转】第5篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:自动注册JS脚本+委托回调方法分析
作者: 牛A与牛C之间 时间: 2013-11-19 分类: 技术文章 | 暂无评论 | 编辑文章 主页 » 技术文章 » 第5篇:Xilium CefGlue 关于 CLR Object 与 JS ...
- 【机器学习实战】第11章 使用 Apriori 算法进行关联分析
第 11 章 使用 Apriori 算法进行关联分析 关联分析 关联分析是一种在大规模数据集中寻找有趣关系的任务. 这些关系可以有两种形式: 频繁项集(frequent item sets): 经常出 ...
- C++11的模板新特性-变长参数的模板
这个特性很赞,直接给例子吧,假如我要设计一个类,CachedFetcher内部可能使用std::map也可能使用std::unordered_map,也可能是其它的map,怎么设计呢?没有C++11变 ...
- C++11外部模板
[C++11之外部模板] 在标准C++中,只要在编译单元内遇到被完整定义的模板,编译器都必须将其实例化(instantiate).这会大大增加编译时间,特别是模板在许多编译单元内使用相同的参数实例化. ...
随机推荐
- Python使用subprocess的Popen要调用系统命令
当我们须要调用系统的命令的时候,最先考虑的os模块.用os.system()和os.popen()来进行操作.可是这两个命令过于简单.不能完毕一些复杂的操作,如给执行的命令提供输入或者读取命令的输出, ...
- nyoj 117 找到的倒数 【树阵】+【分离】
这个问题的解决方案是真的很不错!!! 思路:建立一个结构体包括val和id. val就是输入的数,id表示输入的顺序.然后依照val从小到大排序.假设val相等.那么就依照id排序. 假设没有逆序的话 ...
- 【原创】leetCodeOj --- Copy List with Random Pointer 解题报告
题目地址: https://oj.leetcode.com/problems/copy-list-with-random-pointer/ 题目内容: A linked list is given s ...
- vc++笔记十一
一.LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 连接器LNK是通过调用cvtres.exe完毕文件向coff格式的转换的,所以出现这样的错误的原因就是cvtres.exe出现了问题 ...
- 20那天android得知
20多天的实习(事实上,一个人学习的东西)要结束, 剩下的只是读研. 这项20许多天我学到了很多东西, 对android的发展也有了一定的了解.之后写这篇文章主要完成的研究可以得知快速回升 1.安德鲁 ...
- zTree市县实现三个梯级数据库映射
zTree市县实现三个梯级数据库映射 Province.hbm.xml: <?xml version="1.0" encoding="UTF-8"? &g ...
- Android UI法宝的设计资源的开发
UI再次推荐设计资源.纯干,没有水~ 各种背景资源库 http://subtlepatterns.com/ ICON资源 https://www.iconfinder.com/ watermark/2 ...
- (ArcGIS API For Silverlight )QueryTask 跨层查询,和监控完整的查询!
(ArcGIS API For Silverlight )QueryTask 跨层查询,和监控完整的查询! 直接在源代码: 定义全局变量: int index=0; /// & ...
- 【 D3.js 进阶系列 — 1.1 】 其它表格文件的读取
CSV 表格文件是以逗号作为单元分隔符的,其他还有以制表符 Tab 作为单元分隔符的 TSV 文件,还有人为定义的其他分隔符的表格文件.本文将说明在 D3 中怎样读取它们. 1. TSV 表格文件是什 ...
- WINDOWS7,8和os x yosemite 10.10.1懒人版双系统安装教程
安装过程 磁盘划分 懒人版如果不是整盘单系统或者双硬盘双系统安装我们需要在当前系统磁盘划分两块磁盘空间,一个用来做安装盘,一个作为系统盘. 我这里是单硬盘,想从最后一个盘符压缩出80GB的空来安装黑苹 ...