zoukankan      html  css  js  c++  java
  • ZT 类模板的声明和实现是不能分离的

    http://bbs.csdn.net/topics/380250382

    #9 得分:0 回复于: 2012-03-31 11:19:35
    引用 6 楼  的回复:
    引用 4 楼  的回复:

    通过显示实例化你可以把模版的实现放在 cpp 里, 要不然的话模版实现必须放在 .h 里面.


    好像不显示实例化, 我把模板放在main.cpp里面也没报错啊, 比如你把刚才我那句注释掉, 也可以运行的.

    你是只有一个 cpp 的情况. 如果有多个 cpp 文件再使用这个模版, 你必须把它放在头文件里, 然后每个 cpp 都要 #include 这 个头文件. 显示实例化之后头文件里只需要声明, 然后在其中一个 cpp 里面实现并显示实例化, 其它的 cpp 就可以直接用了.
    具体可以 google 一下 "模版声明实现分离"

    今天本来打算用类模板来实现一些数据结构的
    通用模块,以便以后能直接使用

    可是测试的时候编译器一直
    显示error LNK2001: unresolved external symbol
    的信息。。

    平时很少用模板类写东西,开始以为是语法错误,可是怎么都找不出语法问题
    这时我百度查询下,才知道
    原来类模板的声明和实现不能放在不同的文件中
    即类模板的声明和实现是不能分离的

    究 其原因,是因为类模板和函数模板都不是真正的定义,真正的定义是在模板实体化的时候由编译器完成的。如果将模板的定义部分和实现部分分离开来,编译器真正 要去完成模板实体化的时候就会因为找不到相应的代码而发生链接错误。即error LNK2001: unresolved external symbol

    另外,据说C++标准是要求能实现分离编译的。只不过实现起来难度太高,所以大部分主流编译器(当然也包括VC在内)都不支持这个功能。

    虽然标准委员会出了一个叫EXPORT(你可以在MSDN里查到),但由于实现难度和会严重降低编译器的
    优化作用,所以,至今没有编译器厂商实现了那个关键字。

    所以,你还是习惯把它们写在一起吧。

    毕竟STL也是这样写出来的

    通常我们写通用代码时都习惯.h文件声明,.cpp文件实现功能,调用的时候包含.h文件
    但是,以后大家用模板类实现自己的通用代码时,记得要把类声明和实现写到同一个.h文件或.cpp文件里
    这样才不会出现链接错误!!

    模板类-声明与实现的分离 - Issac U - 存在即合理的博客-Issachttp://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380143fd3d1027fa3c215cc791f11506197ba27241713d5c77f6705b21902b7a52b33715066eccad58b4bd7b191282c8b2434721f854712d51ba9c14726c22a9a47fdea44a7ecff25e2a8c5a0de4323c844727e97f1fb4d711fdd1bfb0340e2b1ed4d025e60ad9c43728f5e6058eb3436b250f890251e029680d94b3dc13da711&p=93759a46d59813e94bbe9b7c7f51&newp=ce769a47ce9c11a05beed53f174492695803ed633dd3da0d20&user=baidu&fm=sc&query=%C4%A3%B0%E6%C9%F9%C3%F7%CA%B5%CF%D6%B7%D6%C0%EB&qid=&p1=4
     
    一堆的undefined reference to...
    通过查询各种搜索引擎,得知,究其原因还是在于,模板类的实现分离过于复杂..导致许多编译器无法实现这个功能.
    而综合各种解决方案最简单的还是两种:
    (1)不分离...声明实现全部放在.h中
    (2)分离,但是要修改main.cpp中的include.
    原来是#include "include/stack.h"

     修改为:#include "src/stack.cpp"

    也就是说直接包含这个cpp文件..等于就是把stack.h和stack.cpp全部包含进来.一起编译.

    C++模板不支持分离编译

    时间:2013-04-17 12:34来源:www.chengxuyuans.com
     

    模板不支持分离编译。你需要把所有的申明和定义放在一个文件里实现

    举个例子,cpp_1.h如下:

    template<class numtype>

    class cpp_1 {

        public:

                numtype a;

                cpp_1(numtype);

    }

    cpp.cpp如下:

    #include "cpp_1.h"

    template<class numtype>

    cpp_1<class numtype>::cpp_1(numtype x){

        a = x;

    }

    main.cpp如下:

    #include "cpp.h"

    int main(){

        cpp_1<int> s(3); //第三行

        return 0;

    }


    因为模板不支持分离编译。上面第三行就会报错,编译器在编译cpp的时候不知道要生成cpp_1<int>::cpp_1(int)的代码,所以link的时候就找不到.

    因此,正确的方法是,把模板的声明实现放在一个文件里。

    本文地址http://www.chengxuyuans.com/download/qianduan/2013/0417/56700.html

  • 相关阅读:
    百度编辑器 Ueditor使用记录
    JS实现继承的几种方式
    IOS 浏览器上设置overflow: auto 不可滚动
    throw new Error('Cyclic dependency' + nodeRep)
    如何理解springaop
    SQL连接的分类
    Eclipse创建Maven-Web项目及解决 jre版本和web.xml版本问题
    SQL的几种连接:内连接、左联接、右连接、全连接、交叉连接
    Centos7下面安装eclipse
    Centos7 下编译 Openjdk8
  • 原文地址:https://www.cnblogs.com/jeanschen/p/3564623.html
Copyright © 2011-2022 走看看