C++程序设计特别版学习笔记(四)

时间:2023-02-12 09:08:42

                                                    前言

          该笔记是在学习裘宗燕翻译的C++程序设计特别版过程总结出的。

  派生和模板

   模板和派生 都是从已有类型构造新类型的机制,通常被用于去写利用各种共性的代码。这两种机制的组合是许多有用技术的基础的。  从一个非模板类派生出一个模板类,这是为一组模板提供一个公用实现的一种方法。  比如:    Template<class T> class Vector<T*>: private Vector<void*> {/*…*/};    从一个模板类派生出另一个模板类也常常很有用。    最常见的情况是基类和派生类具有同样的参数,但是这并不是一项要求。例如  Ex:  Template<class T> class Basic_ops{//  Public:       bool operator ==(const T&)const;       bool operator !=(const T&)const;       //…       Const T& devived()const{ return static_cast< Const T&>(*this);}    };      Template<class T> class Math_container : public Basic_ops< Math_container<T>> {  //… };    保持容器与操作分离的另一种替代技术,就是通过模板参数将它们组合起来。    Template<class T,class C>class Mcontainer    {     C elements; //… Public:  T& operator [](size_t i){return elements[i];}  Friend bool operator ==<>(const Mcontainer&,const Mcontainer&);  Friend bool operator! =<>(const Mcontainer&,const Mcontainer&);  //… };   Template<class T>class My_array{/*…*/};   Mcontainer<double,My_array<double>> mc;   通过类模板生成的类也是完全正常的类,因此也可以有友元。   参数化、继承  虚函数提供的是运行时多态性。  模板提供的是编译时多态性 或者参数多态性。  必须将各种操作在线化,那么应该使用模板。   成员模板  一个类或者模板也可以有包含本身就是模板的成员。    Ex: Template<class Scalar>class complex{ Scalar re,im; Public:  Template<class T>  complex(const complex<T>& c);    //不是复制构造函数  complex(const complex<Scalar>&); // 是复制构造函数 };   如果 T2 可以对T1 初始化,那么 complex<T2> 构造 complex<T1> 模板构造函数绝对不会用于生成复制构造函数,复制赋值也必须定义为非模板运算符。   成员模板不能是virtual.   继承关系 将模板理解为一种有关如何生成特定类的规范,这也是一种很有用的看法。换句话说,模板实现的是一种在需要时能够基于用户描述去生成类型的机制——类型生成器 如果只考虑C++ 语言的规则,在由同一个类模板生成的两个类之间并不存在任何关系。   Ex Class Shape {/*…*/} Class Circle:public Shape{/*…*/};   std::set<Shape* > != std::set<Circle*>   模板转换  由前一节说明,由同一个模板生成的各个类之间并没有任何默认的关系。  然而 我们可以利用重载类型转换运算 来是实现 T2 参数的模板类 到 T1 参数的模板类的转换,只要存在由 T2 T1的转换。    Ex:    Template<class T> class Ptr{//    T* p;    Public:    Ptr(T*);    Ptr(const Ptr&);    Template<class C> operator Ptr<C> ();    };    Template<class T>  Template<class C>  Ptr<T>::operator Ptr<C>(){ return Ptr<C>(p);}    Void f(Ptr<Circle> pc)  { Ptr<Shape> ps = pc; //ok Ptr<Circle> pc2 = ps; // error  }    以上的工作必须在类型转换存在的基础上才能正确运行。   注意:一个模板的参数表与其模板成员的参数表不能组合在一起。  Ex:  Template<class T,class C>   //Error  Ptr<T>:: operator Ptr<C>(){/*…*/};   源代码组织