zoukankan      html  css  js  c++  java
  • C++ 模板的编译 以及 类模板内部的实例化

    在C++中。编译器在看到模板的定义的时候。并不马上产生代码,仅仅有在看到用到模板时,比方调用了模板函数 或者 定义了类模板的

    对象的时候。编译器才产生特定类型的代码。


    一般而言,在调用函数的时候,仅仅须要知道函数的声明就可以;

    在定义类的对象时,仅仅须要知道类的定义,不须要成员函数的定义。


    可是,这对于模板编译是不奏效的。模板要进行实例化,则必须可以訪问定义模板的源码。当调用函数模板以及类模板的成员函数

    的时候,须要知道函数的定义


    标准C++对于模板的编译提供了两种策略:

    同样之处:“将类定义以及函数声明放在头文件里,而函数定义以及成员函数的定义放在源文件里”。

    不同之处:编译器如何使用来自源文件的定义。


    包括编译模型

    编译器必须看到用到的全部的模板的定义。

     

    一般能够在声明类模板以及函数模板的头文件里加入include语句指示该定义可用。即:

    #include “File.cc”    // File.cc是包括了相关函数实现的源文件


    长处:保证了源文件与定义文件的分离。

    缺点:在不论什么使用到该模板的源文件里,编译时,编译器都会为事实上例化一份。也就意味着同一个函数模板可能有多份实例化。在链接的时候。编译器会选择一份实例化,扔掉其它的。

    显然,这整个过程是非常费时的。

     

    分别编译模型:

    编译器会跟踪相关模板的定义,因此我们必须事先告诉编译器。哪些模板是须要记住的。

    使用 exportkeyword能够做到这一点。

     

    每一个模板仅仅能使用exportkeyword一次!!

    因此: 1   在函数模板的定义时指明该函数是可导出的; 2   在类的实现文件里使用exportkeyword,(假设在类定义的文件里使用。那么该头文件仅仅能被某个源文件包括一次!。)。

     

    即: export    template<typename T>   compare  (const T &, const T &) { …. }  // 在函数的实现体指明export

            export    template<class T>    class    myClass; // 在类的实现文件里使用export

     

    注:   尽管有点多余,可是还是说一下。类的定义文件以及实现文件,定义文件是指定义类的成员变量(即属性)的文件。实现文件是实现类的接口的文件。


    值得注意的是:导出类模板的成员自己主动为导出的。

    能够指定类模板的个别成员是可导出的,那么那些不可导出的成员必须遵循 包括编译模型,即定义必须放在定义类模板的文件里。

     

    编译模板本身是非常复杂的工作。可是这对用户而言是透明的,所有交给了编译器来承担,可是对于模板用户来说,仍然有一些难点。


    在模板中,包括两种名字:依赖于模板形參的名字,以及不依赖于模板形參的名字。


    对于模板的设计者来说,保证全部不依赖于模板形參的名字在模板本身的作用于中定义。

    对于模板的使用者来说,保证与模板形參相关的函数、类型以及声明等可见。




    类模板内部的实例化机制:

    在以下的类模板中。有:

    template<class T>

    class Item

    {

     int val;

     Item*next ; //在类的内部能够使用非实例化的版本号,由于编译器默认在类的内部引用类的名字时。使用的是同一版本号。

    };

     

    template<class T>

    class Queue

    {

    public:

      Queue & operator=(const Queue &); //同上

    ….

    private:

      Item<T> *head;  //此处必须类形參,由于编译器不会为类中使用的其它模板进行參数判断。因此须要自己指明。

       Item<T>*tail;

     

    };



  • 相关阅读:
    利用DTrace实时检测MySQl
    改进MySQL Order By Rand()的低效率
    RDS for MySQL查询缓存 (Query Cache) 的设置和使用
    RDS For MySQL 字符集相关说明
    RDS for MySQL 通过 mysqlbinlog 查看 binlog 乱码
    RDS for MySQL Mysqldump 常见问题和处理
    RDS for MySQL Online DDL 使用
    RDS MySQL 表上 Metadata lock 的产生和处理
    RDS for MySQL 如何使用 Percona Toolkit
    北京已成为投融资诈骗重灾区:存好骗子公司黑名单,谨防上当!
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5387492.html
Copyright © 2011-2022 走看看