C 箴言:用成员函数模板接受兼容类型
2008-02-23 05:25:28来源:互联网 阅读 ()
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<typename T> class SmartPtr { public: // smart pointers are typically explicit SmartPtr(T *realPtr); // initialized by built-in pointers ... }; SmartPtr<Top> pt1 = // convert SmartPtr<Middle> => SmartPtr<Middle>(new Middle); // SmartPtr<Top> SmartPtr<Top> pt2 = // convert SmartPtr<Bottom> => SmartPtr<Bottom>(new Bottom); // SmartPtr<Top> SmartPtr<const Top> pct2 = pt1; // convert SmartPtr<Top> => // SmartPtr<const Top> |
在同一个 template(模板)的不同 instantiations(实例化)之间没有 inherent relationship(继承关系),所以编译器认为 SmartPtr<Middle> 和 SmartPtr<Top> 是完全不同的 classes,并不比(比方说)vector<float> 和 Widget 的关系更近。为了得到我们想要的在 SmartPtr classes 之间的转换,我们必须显式地为他们编程。
在上面的 smart pointer(智能指针)的示例代码中,每一个语句创建一个新的 smart pointer object(智能指针对象),所以现在我们就集中于我们如何写 smart pointer constructors(智能指针的构造函数),让他以我们想要的方式运转。一个关键的事实是我们无法写出我们需要的全部 constructors(构造函数)。在上面的 hierarchy(继承体系)中,我们能从一个 SmartPtr<Middle> 或一个 SmartPtr<Bottom> 构造出一个 SmartPtr<Top>,但是假如将来这个 hierarchy(继承体系)被扩充,SmartPtr<Top> objects 还必须能从其他 smart pointer types(智能指针类型)构造出来。例如,假如我们后来加入
class BelowBottom: public Bottom { ... }; |
我们就需要支持从 SmartPtr<BelowBottom> objects 到 SmartPtr<Top> objects 的创建,而且我们当然不希望为了做到这一点而必须改变 SmartPtr template。
大体上,我们需要的 constructors(构造函数)的数量是无限的。因为一个 template(模板)能被实例化而产生无数个函数,所以似乎我们无需为 SmartPtr 提供一个 constructor function(构造函数函数),我们需要一个 constructor template(构造函数模板)。这样的 templates(模板)是 member function templates(成员函数模板)(常常被恰如其分地称为 member templates(成员模板))——生成一个 class 的 member functions(成员函数)的 templates(模板)的范例:
template<typename T> class SmartPtr { public: template<typename U> // member template SmartPtr(const SmartPtr<U>& other); // for a "generalized ... // copy constructor" }; |
这就是说对于每一种类型 T 和每一种类型 U,都能从一个 SmartPtr<U> 创建出一个 SmartPtr<T>,因为 SmartPtr<T> 有一个取得一个 SmartPtr<U> 参数的 constructor(构造函数)。像这样的 constructor(构造函数)——从一个类型是同一个 template(模板)的不同实例化的 object 创建另一个 object 的 constructor(构造函数)(例如,从一个 SmartPtr<U> 创建一个 SmartPtr<T>)——有时被称为 generalized copy constructors(泛型化拷贝构造函数)。
上面的 generalized copy constructor(泛型化拷贝构造函数)没有被声明为 explicit(显式)的。这是故意为之的。built-in pointer types(内建指针类型)之间的类型转换(例如,从派生类指针到基类指针)是隐式的和无需 cast(强制转型)的,所以让 smart pointers(智能指针)模仿这一行为是合理的。在 templatized constructor(模板化构造函数)中省略 explicit 正好做到这一点。
作为声明,SmartPtr 的 generalized copy constructor(泛型化拷贝构造函数)提供的东西比我们想要的还多。是的,我们需要能够从一个 SmartPtr<Bottom> 创建一个 SmartPtr<Top>,但是我们无需能够从一个 SmartPtr<Top> 创建一个 SmartPtr<Bottom>,这就像颠倒 public inheritance(公有继承)的含义(参见《C 箴言:确保公开继承模拟“is-a”》)。我们也无需能够从一个 SmartPtr<double> 创建一个 SmartPtr<int>,因为这和从 int* 到 double* 的 implicit conversion(隐式转换)是不相称的。我们必须设法过滤从这个 member template(成员模板)生成的 member functions(成员函数)的群体。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇: 探索C 的秘密之详解extern
下一篇: C 之父Bjarne谈C 中的STL模板
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash