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所有接口中努力达成这些性质. “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容. “阻止误用"的办法包括建立新类型.限 ...
随机推荐
- java参数传递时到底是值传递还是引用传递
java参数传递时到底是值传递还是引用传递(baidu搜集) 问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解. 原题是:当一 ...
- Fody
Fody https://github.com/Fody/Fody/ 有空还要看下怎么实现的.
- bzoj3170
以前写的,好像忘写解题报告 注意是一个跟曼哈顿距离很有用的结论 |xi-xj|+|yi-yj|=max(|xi+yi-(xj+yj)|,|xi-yi+(xj-yj)|) 因为绝对值有个性质是|a-b| ...
- [原]Unity3D深入浅出 - 物理引擎之碰撞体(Colliders)
通常Colliders会与Rigidbody一起使用,没有添加碰撞体的刚体会彼此相互穿过. 常用碰撞体有以下几种: Box Collider:盒子碰撞体,是一个立方体外形的碰撞体,可调整为不同大小的长 ...
- geetoo编译安装
关于Gentoo发行版的介绍请看:全球最受欢迎的十大Linux发行版(图) Host机环境:Win2008 + VMware 7.1 下载安装包 下载安装 CD 和 stage3 包: http:// ...
- Entity Framework 数据生成选项DatabaseGenerated
在EF中,我们建立数据模型的时候,可以给属性配置数据生成选项DatabaseGenerated,它后有三个枚举值:Identity.None和Computed. Identity:自增长 None:不 ...
- Android 数据传输之MessagePack使用
介绍过什么是MessagePack之后,就进行Android与MessagePack的使用. 在MessagePack的官网上介绍MessagePack与Java结合使用的都是使用Maven作为JAR ...
- application/x-www-form-urlencoded等字符编码的解释说明
关于application/x-www-form-urlencoded等字符编码的解释说明 在Form元素的语法中,EncType表明提交数据的格式 用 Enctype 属性指定将数据回发到服务器时浏 ...
- js基础第3天
仿淘宝搜索框案例(有价值) 判断用户输入事件 正常浏览器:oninput(判断用户输入) ie678浏览器兼容:onpropertychange(因为兼容性问题, ie浏览器678是需要使用这个来判断 ...
- 第一章 :绪论-Twitter数据的收集和处理
为什么要用twitter,我心里是一万头CNM在飞奔.这个国外的东西很不好访问到的,国内的政策,你懂的,不说这个了,还是想办法翻出去再说吧. 不知道别人都用的什么工具,看到太多的注册就头大,就选了一个 ...