Effective C++ 条款45
本节条款的题目是运用成员模板接受全部兼容类型
作者阐述自己的观点是通过智能指针的样例。
在学习本节条款之前我们要先明确关于隐式转化的问题
例如以下代码:
#include<iostream>
using namespace std;
class A
{
public:
explicit A(int i):a(i){};
A(const A&obj):a(obj.a)
{
}
private:
int a;
};
int main()
{
int value =0;
A a = value;//编译不通过。由于构造函数中有explicit限定符
return 0;
}
我们知道由于explicit限定符的存在编译不通过。
以下我们看另一段书上的代码:
template<typename T>
class SmartPrt{
public:
explicit SmartPtr(T* realPtr);
……
};
SmartPtr<Top> pt1=SmartPtr<Middle>(new Middle);
SmartPrt<Top> pt2=SmartPrt<Bottom>(new Bottom);
SmartPrt<const Top> pct2=pt1;
我们能够知道,由于`SmartPtr<Top>`类型和`SmartPtr<Middle>`
类型不同。再加上explicit SmartPtr<Middle>
中的explicit限定符,SmartPtr<Top> pt1=SmartPtr<Middle>(new Middle);
这句代码编译不通过。
并且编译器并不觉得SmartPtr<Top>
类型和SmartPtr<Middle>
类型存在继承关系。
为了能够实现相互转化。能够加入本节的主旨技术去解决上面出现的问题。
例如以下代码:
template<typaname T>
class SmartPtr{
public:
template<typename U>
SmartPrt(const SmartPrt<U>& other)
:heldPrt(other.get()){};
T* get() const{return heldPrt;}
……
private:
T* heldPrt;
};
SmartPtr<Top> pt1=SmartPtr<Middle>(new Middle);
SmartPrt<Top> pt2=SmartPrt<Bottom>(new Bottom);
SmartPrt<const Top> pct2=pt1;
我们加入了一个member function template函数。由于typename T和typename U 是两种类型,并且构造函数中没有explicit关键字,不会阻止heldPrt(other.get())的隐式转换
。
所以,以上代码能够通过编译。
作者最后列出了TR1规范中关于tr1::shared_ptr的一份摘录
例如以下:
template<class T>
class shared_ptr{
public:
template<class Y>
explicit shared_ptr(Y* p);
template<class Y>
shared_ptr(shared_ptr<Y> const& r);
template<class Y>
explicit shared_ptr(weak_ptr<Y> const& r);
template<class Y>
explicit shared_ptr(auto_ptr<Y> const& r);
template<class Y>
shared_ptr& operator=(shared_ptr<Y> const& r);
template<class Y>
shared_ptr& operator=(auto_ptr<Y> const& r);
……
};
我们能够发现上面仅仅有泛化copy构造函数不是explicit,表示shared_ptr 的隐式转化被同意,而其它的智能指针转化不被同意。
这里另一个须要注意的地方,在class类声明泛化copy构造函数(member template)。并不会阻止编译器生成它们自己的copy构造函数(non-template),换言之。假设程序中仅仅写了泛化的copy构造函数,那么编译器还是会自己主动生成一个非泛化的版本号出来,假设不想要这个缺省版本号,那一定不能偷懒。要两个版本号的copy构造函数都要写。
代码例如以下:
template<typaname T>
class SmartPtr{
public:
template<typename U>
SmartPrt(const SmartPrt<U>& other)
:heldPrt(other.get()){};
SmartPtr(){}//假设不写自己的非泛化构造函数,编译器会自己主动生成自己的默认非泛化构造函数。
T* get() const{return heldPrt;}
……
private:
T* heldPrt;
};
最后:
作者总结例如以下:
1. 请使用member function templates(成员函数模板)生成“可接受全部兼容类型”的函数。
2. 假设你声明member templates用于“泛化copy构造”或“泛化assignment操作”,你还是须要声明正常的copy构造函数和copy assignment操作符。
Effective C++ 条款45的更多相关文章
- Effective C++ -----条款45:运用成员函数模板接受所有兼容类型
请使用member function templates(成员函数模板)生成”可接受所有兼容类型“的函数. 如果你声明member templates 用于“泛化copy构造”或“泛化assignme ...
- [More Effective C++]条款22有关返回值优化的验证结果
(这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...
- More Effective C++ 条款0,1
More Effective C++ 条款0,1 条款0 关于编译器 不同的编译器支持C++的特性能力不同.有些编译器不支持bool类型,此时可用 enum bool{false, true};枚举类 ...
- Effective C++规定45 附加代码
这部分是额外的代码的博客.键45条款想法已经实现. #include<iostream> using namespace std; template<typename T> c ...
- Effective C++ 条款08:别让异常逃离析构函数
1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...
- Effective C++ -----条款28:避免返回handles指向对象内部成分
避免返回handles(包括reference.指针.迭代器)指向对象内部.遵守这个条款可增加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(dangling handle ...
- Effective C++ -----条款21:必须返回对象时,别妄想返回其reference
绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个loc ...
- Effective C++ -----条款19:设计class犹如设计type
Class的设计就是type的设计.在定义一个新type之前,请确定你已经考虑过本条款覆盖的所有讨论主题. 新type的对象应该如何被创建和销毁? 对象的初始化和对象的赋值该有什么样的区别? 新typ ...
- Effective C++ -----条款18:让接口容易被正确使用,不易被误用
好的接口很容易被正确使用,不容易被误用.你应该在你IDE所有接口中努力达成这些性质. “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容. “阻止误用"的办法包括建立新类型.限 ...
随机推荐
- Pyhon中的除法
Python中分为3种除法:传统除法.精确除法.地板除. 传统除法: 如果是整数除法则执行地板除,如果是浮点数除法则执行精确除法. >>>1/2 0 >>>1.0/ ...
- 1628. White Streaks(STL)
1628 题意不太好理解 求横黑条 和竖黑条共有多少个 注意1*1的情况 如果横向纵向都是1*1 算为一个 否则不算 用了下vector 枚举找下 #include <iostream> ...
- uva1658 admiral
费用流. 裸的拆点最小费用流,一跑就行. 核弹预警,为何wa20多发.build函数一定要返回true...... 太可怕了 #include<cstdio> #include<al ...
- sencha项目升级
对于已经开发好的sencha项目进行升级,要做的有以下几步(以sencha2.2.0升级到sencha2.3.1为例): 1,下载Sencha-2.3.1sdk,下载地址:http://cdn.sen ...
- SDOI2008Cave 洞穴勘测
无限膜拜CLJ大牛…… 不会动态树的弱弱在CLJ的帮助下AC了此题 我想到了并查集(人人都会想到的吧……囧),但不知道应该如何处理destroy操作…… 其实 make操作的实质就是:把x节点到其所在 ...
- Bsie(鄙视IE)
http://www.bootcss.com/p/bsie/ 欢迎,这是bsie项目主页. 简介 bsie弥补了Bootstrap对IE6的不兼容.Bootstrap是 twitter.com 推出的 ...
- nginx多域名的配置方法
方法一:多个.conf方法 1. 到/usr/local/nginx/ 新建一个目录 vhosts 并创建两个conf文件,如:wodejj.com.conf ,xiaobing.com.conf. ...
- 单点登录系统(SSO)的开发思路
单点登录并不是一个新鲜的玩意儿,比较官方的解释是企业业务整合的解决方案之一,通俗来讲SSO就是一个通用的用户中心,国内比较流行的UCenter就是一套单点登录解决方案.而近期以CSDN明文存储用户密码 ...
- Loader for loading embedded assemblies z
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Ref ...
- MEF技术
MEF 是一个使开发人员能够创建“插件式应用程序”的技术,这里的“插件”是指在应用程序部署后开发人员能够通过开发“插件”来扩展应用程序功能.但不同之处是使用MEF框架您在系统设计阶段不需要考虑在应用程 ...