c++ primary 16章

    技术2022-05-11  65

    1:类模板的具体实现方式:参见P689对于Query模板类如下:template<class type>class Query{public: void query();private: class QueryItem { public:  type getA();  type getB(); private:  type a;  type b; };private: QueryItem *next;//这里不需要什么参数类型了};由于QueryItem属于内部模板类,可以直接使用Query的模板参数。同时作为query的私有类,不需要把Query作为QueryItem类的友元存在,只要

    QueryItem提供Query的接口getA,getB就可以了。如果不如此,则把QueryItem类全部作为共有成员存在。

    两个类模板(QueryItem, Query)的实例时机:上例中首先我们Query<int> QueryInt,这时候先实例化Query类模板,QueryItem没有被实例化,

    只有对next成员解引用的时候才实例化QueryItem类模板。

    2:成员模板 P691成员模板分为两种:1类数据成员模板,2类函数成员模板template<class T>class Query{private: template< class Type > class CL<Type> { public:  Type m;  T    n; };

    public: template< class It> void assign< It first, It last) {  remove();            //call Query<T>::remove() to clear Query<T>  while (first!=last)  {   add(*first);   //call Query<T>::add to set Query<T>   ++first;  }; }; };

    对于assign这样的成员函数中,在标准库的vector容器就用到了,例如:int a[] = { 1, 2,3};vector<int> vt(a[0], a[3);其对应原型如下:vector的member functiontemplate <class InputIterator>void assign(InputIterator first, InputIterator last);

    Erases all elements contained in self, then inserts new elements from the range [first, last).

    对于这样类成员函数模板,对类内的任意成员函数都是适用的。比如构造函数,上述的assign同构造函数形式上的差异仅仅在于名字。

    类成员模板在类外的实现。上述assign可以实现如此:template<class T> template <class It>void Query<T>::assign(It first, It last){....};

    template<class T> template <class Type>class Query<T>::CL<class Type>{....};

    16.8类模板及其编译模式 P695类模板的实例:只有在上下文context要求类模板的完整定义时才被实例。举个例子:new的时候,或者调用成员函数的时候。在仅仅是个引用

    或者指针的时候不需要类的完整定义。具体参见16.2节。

    另外对于构造函数的初始化,尽量使用构造函数表达式来初始化。因为复杂类型(这里指有构造函数的类成员,如string),不要在构造函数

    {}设置,因为这样会构造两次。1:传引用2:初始化表达式

    实例化的时机:原文摘如下针对一个特定类型而实例化类模吧不会引起“针对同一类型自动实例化类模板成员的定义”。只有当程序需要知道成员的定义时(即如果嵌套类被使用时要求它的完整类类型或如果调用成员函数,或如果做成员地址,或如果查看静态数据成员的值)成员才会被实例化。

    编译模式的分类:1:包含模式。即类模板的定义都放在同一个头文件中实现,可以是作为inline函数,或者不作为inline函数,在头文件中定义。2:分离模式:定义(实现文件)和声明(头文件)分开,这里头文件中需要增加export关键字说明。这个关键字放在头文件中的template关键字前即可(这样整个类模板被export)。例如: Query.hexport template < class T>Query{...};

    export关键字的作用:告诉编译器,当使用一个类模板的成员函数实例或者静态数据成员实例时,只“要求”类模板的定义。

    针对单个成员的export//--Query.htemplate<class Type>class Query{public: void remove(); void add(const Type &);};

    template <class Type>void Query<Type>::remove(){...};

    //--Query.cpp#include "query.h"

    temlate<class Type>export void Query<Type>::add(..){...}

    模板的显示实例申明 explicit instantiation declaration#include "Query.h"   //--这里需要提供全部的Query模板类的定义template class Query<int>;对于这样的申明,需要使用编译选项“抑制模板隐式实例化”来避免对同一个模板类多次申明。

    16.9模板特化  P700 ~ P704#include <iostream>template <class Type>class Compare{public:Type max(Type a, Type b);} ;

    template<class Type>Type Compare<Type>::max(Type a, Type b){        return (a>b)?a:b;} ;

    template<>double Compare<double>::max(double a, double b){        return 1;}                ;

    int main(int argc, char* argv[]){        Compare<int> com;        std::cout << com.max(30,20) << std::endl;        Compare<double> com_d;        std::cout << com_d.max(4.4, 5.5) <<std::endl ;        return 0;}

    16.11 类模板的名字解析 P705

    16.12 名字空间和类模板 P707

    16.13 模板数组类 P709


    最新回复(0)