real pointers(真正的指针)做得很好的一件事是支持 implicit conversions(隐式转换)。derived class pointers(派生类指针)隐式转换到 base class pointers(基类指针),pointers to non-const objects(指向非常量对象的指针)转换到 pointers to const objects(指向常量对象的指针),等等。例如,考虑在一个 three-level hierarchy(三层继承体系)中能发生的一些转换:
class Top { ... };
class Middle: public Top { ... };
class Bottom: public Middle { ... };
Top *pt1 = new Middle; // convert Middle* => Top*
Top *pt2 = new Bottom; // convert Bottom* => Top*
const Top *pct2 = pt1; // convert Top* => const Top*
在 user-defined smart pointer classes(用户定义智能指针类)中模仿这些转换是需要技巧的。我们要让下面的代码能够编译:
template
class SmartPtr {
public: // smart pointers are typically
explicit SmartPtr(T *realPtr); // initialized by built-in pointers
...
};
SmartPtr
pt1 = // convert SmartPtr
=>
SmartPtr
(new Middle); // SmartPtr
SmartPtr
pt2 = // convert SmartPtr
=>
SmartPtr
(new Bottom); // SmartPtr
SmartPtr
pct2 = pt1; // convert SmartPtr
=>
// SmartPtr
在同一个 template(模板)的不同 instantiations(实例化)之间没有 inherent relationship(继承关系),所以编译器认为 SmartPtr
在上面的 smart pointer(智能指针)的示例代码中,每一个语句创建一个新的 smart pointer object(智能指针对象),所以现在我们就集中于我们如何写 smart pointer constructors(智能指针的构造函数),让它以我们想要的方式运转。一个关键的事实是我们无法写出我们需要的全部 constructors(构造函数)。在上面的 hierarchy(继承体系)中,我们能从一个 SmartPtr
class BelowBottom: public Bottom { ... };
我们就需要支持从 SmartPtr
大体上,我们需要的 constructors(构造函数)的数量是无限的。因为一个 template(模板)能被实例化而产生无数个函数,所以好像我们不需要为 SmartPtr 提供一个 constructor function(构造函数函数),我们需要一个 constructor template(构造函数模板)。这样的 templates(模板)是 member function templates(成员函数模板)(常常被恰如其分地称为 member templates(成员模板))――生成一个 class 的 member functions(成员函数)的 templates(模板)的范例:
template
class SmartPtr {
public:
template
// member template
SmartPtr(const SmartPtr
& other); // for a "generalized
... // copy constructor"
};
这就是说对于每一种类型 T 和每一种类型 U,都能从一个 SmartPtr 创建出一个 SmartPtr
上面的 generalized copy constructor(泛型化拷贝构造函数)没有被声明为 explicit(显式)的。这是故意为之的。built-in pointer types(内建指针类型)之间的类型转换(例如,从派生类指针到基类指针)是隐式的和不需要 cast(强制转型)的,所以让 smart pointers(智能指针)模仿这一行为是合理的。在 templatized constructor(模板化构造函数)中省略 explicit 正好做到这一点。
作为声明,SmartPtr 的 generalized copy constructor(泛型化拷贝构造函数)提供的东西比我们想要的还多。是的,我们需要能够从一个 SmartPtr