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).这会大大增加编译时间,特别是模板在许多编译单元内使用相同的参数实例化. ...
随机推荐
- [模式识别].(希腊)西奥多里蒂斯<第四版>笔记8它__模板匹配
在语音识别方面,同样的话都是同一个人,每次说的情况是不同的,难以识别.本章是定义如何适应不同的情况有不同的特性指标. 1,基于最优路径搜索的度量:①贝尔曼最优性原则和动态编程②编辑距离(The E ...
- django1.7 配置demo教程(环境搭建)
近期又用到django做个简单项目,1年多没用过了有些手生,按理说没啥问题吧 以下是一个简单的环境搭建demo过程: 前提条件:准备了python2.7已经安装 1.搭建django环境下载 http ...
- 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)
原文:乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) 作者:weba ...
- 解决PhpCms V9后台无法上传图片
PHPCMS V9 在近期一次更新的版本号(9.4.2)中因为代码推断失误.导致PHPCMS在后台更新文章无法上传图片而导致的bug.在PHPCMS论坛中找到了暂时解决方式,希望PHPCMS官方能尽快 ...
- SQL Server 2008 新增T-SQL 简写语法
1.定义变量时可以直接赋值 DECLARE @Id int = 5 2.Insert 语句可以一次插入多行数据 INSERT INTO StateList VALUES(@Id, 'WA'), (@I ...
- Android利用网络编程HttpClient批量上传(一个)
请尊重他人的劳动成果.转载请注明出处:Android网络编程之使用HttpClient批量上传文件 我曾在<Android网络编程之使用HTTP訪问网络资源>一文中介绍过HttpCient ...
- dapper支持oracle游标
dapper支持oracle游标 Dapper是一个轻型的ORM类.它有啥优点.缺点相信很多朋友都知道了,园里也有很多朋友都有相关介绍,这里就不多废话. 如果玩过Oracle都知道,存储过程基本都是通 ...
- SQLSERVER中的log block校验(译)
原文:SQLSERVER中的log block校验(译) SQLSERVER中的log block校验(译) 来自:http://sankarreddy.com/2010/03/transaction ...
- ListView分页显示
出在:http://blog.csdn.net/tu_bingbing/article/details/13275107 当ListView要显示的数据过多时,为了更快的响应用户,这个 ...
- 编程基础——C/C++,Java,ObjC讨论回调模式
什么是回调? 因为它是从C开始进入编程世界.术语改只是口.叫习惯了.java里通常叫listener(监听器).C/C++里通常叫callback(回调),ObjC里面叫delegate(托付) 回调 ...