标签:
1. "智能指针"是行为像指针的对象,但它们能提供指针没有的功能:shared_ptr,weak_ptr,auto_ptr(见条款13)实现对堆内存的自动管理,STL的迭代器实现对整个容器的遍历等.
真正的指针的优势在于支持继承层次中派生类指针向基类指针的转换(当然标准库shared_ptr,weak_ptr,auto_ptr等已实现).
2. 由于同一template的不同具现体之间没有直接联系,也就是说对于自定义的智能指针(假设名为SmartPtr),如果不额外采取手段支持基层层次中派生类指针向基类指针的转换,那么SmartPtr<Base>和SmartPtr<Derived>将会被编译器认为毫无关联,也就不存在SmartPtr<Derived>向SmartPtr<Base>的隐式转换.
要获得Smart classes之间的隐式转换能力,就要明确地写出用于隐式转换的构造函数.
假设存在一个Base类,要实现由SmartPtr<Base的派生类>向SmartPtr<Base>的转换,显然无法为SmartPtr写出所有用于隐式类型转换的copy构造函数,因为Base的继承体系的扩充可能性是无限的.因此只能采用成员函数模板做到一劳永逸:
template<typename T> class SmartPtr{ public: template<typename U> SmartPtr(const SmartPtr<U>& other); //生成copy构造函数用于隐式转换 .... }
以上代码SmartPtr的copy构造函数的含义是对于任何类型U和类型T,都可以根据类型Smart<U>生成一个Smart<T>,因为SmartPtr<U>和SmartPtr<T>是同一template的不同具现体,因此这种构造函数被称为泛化copy构造函数.SmartPtr的泛化copy构造函数并没有被声明为explict,是为了模仿原始指针之间的隐式转换.
以上copy构造函数的声明并无法将SmartPtr之间的转换局限在可转换的原始指针之间,因此要在SmartPtr实现中SmartPtr之间的转换进行限制,假设SmartPtr像auto_ptr一样提供了用于获取原始指针的get函数,那么SmartPtr(const SmartPtr<U>& other)的实现可能像这样:
template<typename T> class SmartPtr{ public: template<typename U> SmartPtr(const SmartPtr<U>& other):helder(other.get()){} T* get() const { return haldPtr; } ... private: T* heldPtr; }
这样就把检查底层指针能否转换的任务交由底层指针来自行检查.
3. 成员模板函数(member template function)的效用并不局限于构造函数,它们的另一个常见作用是支持赋值操作.tr1的shared_ptr支持所有"来自兼容"之内置指针,tr1::shared_ptrs,auto_ptrs和weak_ptrs"的构造行为,以及所有来自上述物(除weak_ptr)的的赋值操作,以下是摘自TR1规范中关于tr1::shared_ptr的一份摘录:
template<typename T> class shared_ptr{ public: template<class Y> //声明类型参数时class和typename含义相同 explict shared_ptr(Y* p); template<class Y> shared_ptr(shared_ptr<Y> const& r); template<class Y> explict shared_ptr(weak_ptr<Y> const& r); template<class Y> explict 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); ... }
以上所有构造函数都为explict,唯有泛化copy构造函数除外,这意味着shared_ptr允许shared_ptr之间的隐式类型转换,而禁止原始指针或其他智能指针类型向shared_ptr的住阿奴换;此外,传递给tr1::shared_ptr构造函数和赋值操作符的auto_ptr并未被声明const,因为auto_ptr在这之后会被置为NULL.
4. 需要注意的是,虽然成员函数模板(member function template)可以具现化出用于shared_ptr<T>向shared_ptr<T>转换的copy构造函数,但如果没有声明copy构造函数,比哪一期还是会合成一个,所以不能依赖于成员函数模板的具现化,要手动声明一个普通的copy构造函数.copy赋值操作符也是一样.
Effective C++ 条款45 运用成员函数模板接受所有兼容类型
标签:
原文地址:http://www.cnblogs.com/reasno/p/4802034.html