本节条款的题目是运用成员模板接受全部兼容类型

作者阐述自己的观点是通过智能指针的样例。

在学习本节条款之前我们要先明确关于隐式转化的问题

例如以下代码:

#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的更多相关文章

  1. Effective C++ -----条款45:运用成员函数模板接受所有兼容类型

    请使用member function templates(成员函数模板)生成”可接受所有兼容类型“的函数. 如果你声明member templates 用于“泛化copy构造”或“泛化assignme ...

  2. [More Effective C++]条款22有关返回值优化的验证结果

    (这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...

  3. More Effective C++ 条款0,1

    More Effective C++ 条款0,1 条款0 关于编译器 不同的编译器支持C++的特性能力不同.有些编译器不支持bool类型,此时可用 enum bool{false, true};枚举类 ...

  4. Effective C++规定45 附加代码

    这部分是额外的代码的博客.键45条款想法已经实现. #include<iostream> using namespace std; template<typename T> c ...

  5. Effective C++ 条款08:别让异常逃离析构函数

    1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...

  6. Effective C++ -----条款28:避免返回handles指向对象内部成分

    避免返回handles(包括reference.指针.迭代器)指向对象内部.遵守这个条款可增加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(dangling handle ...

  7. Effective C++ -----条款21:必须返回对象时,别妄想返回其reference

    绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个loc ...

  8. Effective C++ -----条款19:设计class犹如设计type

    Class的设计就是type的设计.在定义一个新type之前,请确定你已经考虑过本条款覆盖的所有讨论主题. 新type的对象应该如何被创建和销毁? 对象的初始化和对象的赋值该有什么样的区别? 新typ ...

  9. Effective C++ -----条款18:让接口容易被正确使用,不易被误用

    好的接口很容易被正确使用,不容易被误用.你应该在你IDE所有接口中努力达成这些性质. “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容. “阻止误用"的办法包括建立新类型.限 ...

随机推荐

  1. [swustoj 1021] Submissions of online judge

    Submissions of online judge(1021) 问题描述 An online judge is a system to test programs in programming c ...

  2. 什么是Zookeeper,Zookeeper的作用是什么,在Hadoop及hbase中具体作用是什么

    什么是Zookeeper,Zookeeper的作用是什么,它与NameNode及HMaster如何协作?在没有接触Zookeeper的同学,或许会有这些疑问.这里给大家总结一下. 一.什么是Zooke ...

  3. 解决angular的post请求后SpringMVC后台接收不到参数值问题的方法

    这是我后台SpringMVC控制器接收isform参数的方法,只是简单的打出它的值: @RequestMapping(method = RequestMethod.POST) @ResponseBod ...

  4. 【CSS】

    12个很少被人知道的CSS事实 通过CSS禁止Chrome自动为输入框添加橘黄色边框http://www.solagirl.net/override-chromes-automatic-border- ...

  5. 【转】Java 截取字符串

    原文网址:http://blog.csdn.net/yelangjueqi/article/details/9149699 截取字符串常用方法: 1.length() 字符串的长度 例:char ch ...

  6. Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别?

    一个帖子的整理: Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别如果你不带参数的实例化:Handler ...

  7. 7、四大组件之二-Service高级

    一.Native Service 1>什么是Native Service 使用JNI编写,在系统启动完成之前启动的系统级服务. 2>哪些服务是Native Service ACCESSIB ...

  8. HDU4578 Transformation 线段树

    这个题让我重新学习了加 乘 在区间的操作 题解:http://blog.csdn.net/guognib/article/details/25324025?utm_source=tuicool& ...

  9. Codeforces 633 C Spy Syndrome 2 字典树

    题意:还是比较好理解 分析:把每个单词反转,建字典树,然后暴力匹配加密串 注:然后我就是特别不理解,上面那种能过,而且时间很短,但是我想反之亦然啊 我一开始写的是,把加密串进行反转,然后单词正着建字典 ...

  10. tomcat 容器中的UML架构图