关于模板分离编译问题

这几天搞数据经过,当我把做好的类做成模版时分开是老是报错,但好像以前在《C++Primer》中有点模板编译模型的印象,但总也想不起来(快哭了,看来学得真不咋的),看来得温故知新了

       一般将做好的模板分开编译后就出现了如下的错误:

1>  main.cpp
1>  正在生成代码...
1>main.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall List<int>::List<int>(void)" (??0?$List@H@@QAE@XZ),该符号在函数 _main 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 "public: bool __thiscall List<int>::AddTail(int const &)" (?AddTail@?$List@H@@QAE_NABH@Z),该符号在函数 _main 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 "public: int __thiscall List<int>::GetCount(void)" (?GetCount@?$List@H@@QAEHXZ),该符号在函数 _main 中被引用
1>F:\开发区\数据结构和算法\线性表\链表\Debug\链表.exe : fatal error LNK1120: 3 个无法解析的外部命令

为什么会出现这样的问题呢?这其实像是遇到的函数只申明而没有定义的情况。

其实啊在C++Primer这本书中讲到模板编译模型时有:

       当编译器看到模板定义的时候,它不立即产生代码。只有在看到用到的模板时,如果调用了函数模板或调用了类模板的对象的时候,编译器才会产生特定的模板实例。

一般而言,当调用函数的时候,编译器只需要看到函数的申明。类似的,定义类类型的对象时,类定义必须可用,但成员函数的定义不是必须存在的。因此,应该将类定义和函数申明放在头文件中,而普通函数和类成员函数的定义放在源文件中。

     但模板则不同:要进行实例化,编译器必须能够访问定义模板的源代码。当调用函数模板或类模板的成员函数的时候,编译器需要函数的定义,需要那些通常放在源文件中的代码。

    标准C++为编译模板代码定义了两种模型。在两种模型中,构造程序的方式很大程度上是相同的:类定义和函数声明放在头文件中,而函数定义和成员定义放在源文件中。两种模型的不同在于,编译器怎样使用来自源文件的定义。所有编译器的支持“包含”模型,只有一些编译器支持第二种模型,“分别编译”模型。


    1.包含编译模型

在包含编译模型中,编译器必须看到用到的所有模板的定义,一般而言,可以通过在声明函数模板或类模板的头文件中添加一条#include指示使定义可用,该#include引入了包含相关定义的源文件:

#ifndef LIST_H_H

#define LIST_H_H

//声明你所要定义的内容

。。。。。。

#include "List.cpp"

#endif

即可

这一种方法使我们能够保持头文件和实现文件的分离,但需要保证编译器在编译使用模板代码的时候能看到两种文件。

但是,好像不适合类类型模板,反正我的是失败了。。。求求证抓狂

2.分别编译模型

在分别编译模型中,编译器会为我们跟踪相关的模板定义。但是,我们必须让编译器知道要记住给定的模板定义,可以使用export关键字来做这件事。

export关键字能够指明给定可能会需要在其他文件中产生实例化。在一个程序中,一个模板只能定义为导出一次。编译器在需要产生这些实例化时计算出怎样单位模板定义。

exprot关键字不必在模板声明中出现。

  一般我们在函数模板的定义中指明函数模板为导出的,这是通过在关键字template之前包含export关键字而实现的:

export  template  <class T>

T sum(T t1, T t2)  /*...*/

这个函数模板的声明像通常一样应放在头文件中,声明不必指定export。

而类模板的使用export更复杂一些。通常,类声明必须放在头文件中,头文件的类定义体不应该使用关键字export,如果在头文件中使用了export,则该文件只能被程序中的一个源文件使用。

相反,应该在类的实现文件中使用export:

//头文件

template  <class T> class List

{......};


//实现文件

export  template  <class T> class List;

#include "List.h"

......

导出类为声明自动导出的。


很可惜,我使用的是VS2012,到现在第二种方法还不支持。。。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值