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所有接口中努力达成这些性质. “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容. “阻止误用"的办法包括建立新类型.限 ...
随机推荐
- MAC 上搭建lua环境
一.下载并安装 (1)最新release版下载地址 http://www.lua.org/ftp/lua-5.3.1.tar.gz (2)编译 Building Lua is implemented ...
- sublime text格式化插件
sublime text 软件其实是自带格式化插件的,但是它默认的格式化插件,不太好用,且没有快捷键(虽然自己可以设置). 其默认的格式化是在 Edit -> Line -> Re ...
- bzoj1607: [Usaco2008 Dec]Patting Heads 轻拍牛头
筛法. 枚举每个数,它会对它的倍数的答案有贡献. 数大了以后,倍数相应少了很多.比枚举每个数的约数要好的多. 自己yy了一种分步做法.小于sqrt(m)被当作约数枚举,大于sqrt(m)的枚举倍数. ...
- Sencha touch Panel之间的跳转(如不使用TabPanel或者Carousel控件而产生跳转的动画效果)
常规的Sencha touch 应用都是"header content footer"结构,这样的结构无疑将使用TabPanel来实现,而且TabPanel肯定是card布局,这样 ...
- BZOJ2668: [cqoi2012]交换棋子
题解: 可以戳这里:http://www.cnblogs.com/zig-zag/archive/2013/04/21/3033485.html 其实自己yy一下就知道这样建图的正确性了. 感觉太神奇 ...
- BZOJ3451: Tyvj1953 Normal
题解: 好神的一道题.蒟蒻只能膜拜题解. 考虑a对b的贡献,如果a是a-b路径上第一个删除的点,那么给b贡献1. 所以转化之后就是求sigma(1/dist(i,j)),orz!!! 如果不是分母的话 ...
- Excel 内容粘贴到DataGridView, DataGridView 粘贴到 Excel
void dataGridView1_KeyDown(object sender, KeyEventArgs e) { if (e.Control && e.KeyCode == Ke ...
- OK335xS EMMC Partition hacking
#! /bin/sh # # OK335xS EMMC Partition hacking # 说明: # 本文主要是为了解读同事对EMMC分区的写法,其中有很多写法重复了,但 # 依然尽量保留其作者 ...
- Java [Leetcode 242]Valid Anagram
题目描述: Given two strings s and t, write a function to determine if t is an anagram of s. For example, ...
- Windows 下目录及文件向Linux同步
本文解决的是Windows 下目录及文件向Linux同步的问题,Windows向 Windows同步的请参考:http://www.idcfree.com/article-852-1.html 环境介 ...