AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > C++

C++箴言:用成员函数模板接受兼容类型

51自学网 http://www.wanshiok.com

  我们通过 member initialization list(成员初始化列表),用 SmartPtr<U> 持有的类型为 U* 的指针初始化 SmartPtr<T> 的类型为 T* 的 data member(数据成员)。这只有在“存在一个从一个 U* 指针到一个 T* 指针的 implicit conversion(隐式转换)”的条件下才能编译,而这正是我们想要的。最终的效果就是 SmartPtr<T> 现在有一个 generalized copy constructor(泛型化拷贝构造函数),它只有在传入一个 compatible type(兼容类型)的参数时才能编译。

  member function templates(成员函数模板)的用途并不限于 constructors(构造函数)。它们的另一个常见的任务是用于支持 assignment(赋值)。例如,TR1 的 shared_ptr(再次参见《C++箴言:使用对象管理资源》)支持从所有兼容的 built-in pointers(内建指针),tr1::shared_ptrs,auto_ptrs 和 tr1::weak_ptrs构造,以及从除 tr1::weak_ptrs 以外所有这些赋值。这里是从 TR1 规范中摘录出来的一段关于 tr1::shared_ptr 的内容,包括它在声明 template parameters(模板参数)时使用 class 而不是 typename 的偏好。(就像《C++箴言:理解typename的两个含义》中阐述的,在这里的上下文环境中,它们的含义严格一致。)

template<class T> class shared_ptr {
public:
 template<class Y> // construct from
 explicit shared_ptr(Y * p); // any compatible
 template<class Y> // built-in pointer,
 shared_ptr(shared_ptr<Y> const& r); // shared_ptr,
 template<class Y> // weak_ptr, or
 explicit shared_ptr(weak_ptr<Y> const& r); // auto_ptr
 template<class Y>
 explicit shared_ptr(auto_ptr<Y>& r);
 template<class Y> // assign from
 shared_ptr& operator=(shared_ptr<Y> const& r); // any compatible
 template<class Y> // shared_ptr or
 shared_ptr& operator=(auto_ptr<Y>& r); // auto_ptr
 ...
};

  除了 generalized copy constructor(泛型化拷贝构造函数),所有这些 constructors(构造函数)都是 explicit(显式)的。这就意味着从 shared_ptr 的一种类型到另一种的 implicit conversion(隐式转换)是被允许的,但是从一个 built-in pointer(内建指针)或其 smart pointer type(智能指针类型)的 implicit conversion(隐式转换)是不被许可的。(explicit conversion(显式转换)——例如,经由一个 cast(强制转型)——还是可以的。)同样引起注意的是 auto_ptrs 被传送给 tr1::shared_ptr 的 constructors(构造函数)和 assignment operators(赋值操作符)的方式没有被声明为 const,于此对照的是 tr1::shared_ptrs 和 tr1::weak_ptrs 的被传送的方式。这是 auto_ptrs 被复制时需要独一无二的被改变的事实的一个必然结果(参见《C++箴言:使用对象管理资源》)。

  member function templates(成员函数模板)是一个极好的东西,但是它们没有改变这个语言的基本规则。《C++箴言:了解C++偷偷加上和调用了什么》阐述的编译器可以产生的四个 member functions(成员函数)其中两个是 copy constructor(拷贝构造函数)和 copy assignment operator(拷贝赋值运算符)。tr1::shared_ptr 声明了一个 generalized copy constructor(泛型化拷贝构造函数),而且很明显,当类型 T 和 Y 相同时,generalized copy constructor(泛型化拷贝构造函数)就能被实例化而成为 "normal" copy constructor(“常规”拷贝构造函数)。那么,当一个 tr1::shared_ptr object 从另一个相同类型的 tr1::shared_ptr object 构造时,编译器是为 tr1::shared_ptr 生成一个 copy constructor(拷贝构造函数),还是实例化 generalized copy constructor template(泛型化拷贝构造函数模板)?

  就像我说过的,member templates(成员模板)不改变语言规则,而且规则规定如果一个 copy constructor(拷贝构造函数)是必需的而你没有声明,将为你自动生成一个。在一个 class 中声明一个 generalized copy constructor(泛型化拷贝构造函数)(一个 member template(成员模板))不会阻止编译器生成它们自己的 copy constructor(拷贝构造函数)(非模板的),所以如果你要全面支配 copy construction(拷贝构造),你必须既声明一个 generalized copy constructor(泛型化拷贝构造函数)又声明一个 "normal" copy constructor(“常规”拷贝构造函数)。这同样适用于 assignment(赋值)。这是从 tr1::shared_ptr 的定义中摘录的一段,可以作为例子:

template<class T> class shared_ptr {
 public:
  shared_ptr(shared_ptr const& r); // copy constructor

  template<class Y> // generalized
  shared_ptr(shared_ptr<Y> const& r); // copy constructor

  shared_ptr& operator=(shared_ptr const& r); // copy assignment
 
  template<class Y> // generalized
  shared_ptr& operator=(shared_ptr<Y> const& r); // copy assignment
  ...
};

  Things to Remember

  ·使用 member function templates(成员函数模板)生成接受所有兼容类型的函数。

  ·如果你为 generalized copy construction(泛型化拷贝构造)或 generalized assignment(泛型化赋值)声明了 member templates(成员模板),你依然需要声明 normal copy constructor(常规拷贝构造函数)和 copy assignment operator(拷贝赋值运算符)。

 
 

上一篇:创建位图型不规则窗体(可透明,可移动)  下一篇:C++&nbsp;BUILDER&nbsp;动态建立菜单及菜单事件