在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;

};

C++ 模板的编译 以及 类模板内部的实例化的更多相关文章

  1. C++—模板(2)类模板与其特化

    我们以顺序表为例来说明,普通顺序表的定义如下: typedef int DataType; //typedef char DataType; class SeqList { private : Dat ...

  2. 类模板、Stack的类模板实现(自定义链栈方式,自定义数组方式)

    一.类模板 类模板:将类定义中的数据类型参数化 类模板实际上是函数模板的推广,可以用相同的类模板来组建任意类型的对象集合 (一).类模板的定义 template  <类型形参表> clas ...

  3. C++ —— 类模板的分离式编译

    目录 对于C++中类模板的分离式编译的认识 具体的实例 1.对于C++中类模板的分离式编译的认识 为什么C++编译器不能支持对模板的分离式编译(博文链接) 主要内容:编译器编译的一般工作原理.对模版的 ...

  4. C++ 函数模板与类模板(使用 Qt 开发编译环境)

    注意:本文中代码均使用 Qt 开发编译环境,如有疑问和建议欢迎随时留言. 模板是 C++ 支持参数化程序设计的工具,通过它可以实现参数多态性.所谓参数多态性,就是将程序所处理的对象的类型参数化,使得一 ...

  5. C++ 类模板的使用

    从事C++挺久了,在前段时看书时,发现高手,都是在写模板无,泛型编程,顿感差距.自己连模板都没有写,于是就小小的研究了下模板的用法. 模板简而言之就是对某此对象的相同方法,或处理方式,进行归纳,总结, ...

  6. c++的函数模板和类模板

    函数模板和普通函数区别结论: 函数模板不允许自动类型转化 普通函数能够进行自动类型转换 函数模板和普通函数在一起,调用规则: 1 函数模板可以像普通函数一样被重载 2 C++编译器优先考虑普通函数 3 ...

  7. C++_进阶之函数模板_类模板

     C++_进阶之函数模板_类模板 第一部分 前言 c++提供了函数模板(function template.)所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来 ...

  8. C++复习:函数模板和类模板

    前言 C++提供了函数模板(function template).所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表.这个通用函数就称为函数模板.凡是函数体 ...

  9. 【C++】C++中的类模板

    基础的类模板 模板类的继承 内部声明定义普通模板函数和友元模板函数 内部声明友元模板函数+外部定义友元模板函数 声明和定义分别在不同的文件(模板函数.模板友元) C++中有一个重要特性,那就是模板类型 ...

随机推荐

  1. Django基础 - 修改默认SQLite3数据库连接为MySQL

    Django数据库连接默认为SQLite3,打开setting.py可以看到数据库部分的配置如下: DATABASES = { 'default': { 'ENGINE': 'django.db.ba ...

  2. Luogu P4894 【GodFly求解法向量】

    个人感觉我的解法比官方题解好理解得多 因为是任意一个法向量嘛,不妨设$x=1$ 然后解一个二元一次方程就可以解决了 但是因为要求输出三个整数 代码 #include<iostream> # ...

  3. 2016-2017-2 20155309南皓芯《java程序设计》第九周学习总结

    教材内容介绍 一 JDBC简介 JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行操作,开发人员无须接触底层数据库驱动程序的差异性 JDBC标准分为两个部分:J ...

  4. 在Visio里加上、下标方法

    添加上标:选中要成为上标的文字,ctrl+shift+“=” 添加下标:选中要成为下标的文字,ctrl+“=”

  5. Spark(五)Spark任务提交方式和执行流程

    一.Spark中的基本概念 (1)Application:表示你的应用程序 (2)Driver:表示main()函数,创建SparkContext.由SparkContext负责与ClusterMan ...

  6. Hive(八)Hive的Shell操作与压缩存储

    一.Hive的命令行 1.Hive支持的一些命令 Command Description quit Use quit or exit to leave the interactive shell. s ...

  7. JS 如何准确获取当前页面URL网址信息

    在WEB开发中,时常会用到javascript来获取当前页面的url网址信息,在这里是一些获取url信息的小总结. 下面我们举例一个URL,然后获得它的各个组成部分:http://i.cnblogs. ...

  8. hadoop出现error包问题记录

    前段时间,我公司发现大部分hadoop服务器有重传数据包和error包现象,且重传率经常超过1%.zabbix告警hadoop主机有error包出现.收到大量类似如下告警信息: Trigger: et ...

  9. python中发送邮件各种问题

    其实问题主要集中的QQ企业邮箱中,特别坑爹...代码如下: from email.mime.multipart import MIMEMultipart from email.mime.base im ...

  10. 8-3 Bits Equalizer uva12545

    题意: 给出字符串s包含'0' '1' '?'; 再给出字符串t只包含01: 现在我们可以对S做三个操作:把0变成1,把?变成0或1,任意两个位置交换: 问最少操作几次s == t: 贪心 默认除去那 ...