wjyc

导航

置入式模型inclusion model和显示具现化

1、置入式模型

链接错误:

大多数非模板程序代码的组织如下:A,类声明在头文件中; B:全局变量和非inline函数在cpp文件中定义

但是,如果模板程序也这样组织,则会出错。原因在于:函数模板的定义没有被实体化。为了实例化一个模板,编译器必须知道以哪一份定义以及哪些参数对其进行实例化。如果把声明放在h文件,定义放在cpp文件,这编译器无法知道这些信息。因此当编译器发现调用该函数模板时,无法找到其定义,无法以具体的数据类型来实体化该模板函数。于是编译器假设该函数模板的定义位于其他某处,因而只生成一个队它的引用,并将这个引用所指定的定义由链接器去决定。另一方面,当编译器调用该函数模板时,它又无法决定以哪个类型来实例化该定义。

 

就像处理inline函数一样,解决该问题的办法是:

A、把template定义放到H头文件中,这种方法叫作置入式模型。非inline模板函数并不在调用时被展开。每当他们被实体化时,编译器便从新创建一份函数式拷贝。由于这个过程是自动化,因此在同一个cpp文件中可能存在一个模板的两个两个实体化拷贝,而某些链接器会因为发现两份拷贝会报错

B、将定义的cpp文件包含到h文件末尾,即在h文件末尾添加:#include " *.cpp"

C、也可以在用到该模板的每个cpp中添加:#include " *.cpp"

 

2、显示具现化

显示具现化由两部分组成:A、首先是关键字template;B、模板参数已经被全部替换后的函数声明。对于成员函数或者静态成员函数都可以采用该类方法来实例化。

如:template MyClass<int>::MyClass();//明确地以int对MyClass<>类进行实例化

template int const & MyMax(int const & a, int const &b);//对函数模板MyMax以int实例化

 

可以明确要求编译器对类以某种元素显示实例化:template class MyClass<double>;

对某个成员函数以某种类型实例化:template MyClass<string>::MyClass();

                                                        template void MyClass<string>::push(string const & );

但是不能将已经显示实例化的成员函数实例化为其他类型函数:template MyClass<double>::MyClass();

 

在程序中,每个物体只能有一份显示实例化。

posted on 2016-04-01 14:59  wjyc  阅读(237)  评论(0编辑  收藏  举报