C++模板定义和实现分离导致的编译错误
2016-07-21 20:59
417 查看
今天在实现一个二叉树的时候,用到了模板,没在意,和平时一样写了两个文件:BinaryTree.h,BinaryTree.cpp。思路和平时一样,h文件中定义了模板类,然后在cpp文件中实现了一些功能函数。
然后在test.cpp中测试,遇到了一些问题、
问题出现如下:
使用g++直接编译的时候提示,基本上都是undefined reference to错误:
分别编译单独文件,均可生成 .o文件,所以排除单个文件本身的错误
连接两个o文件时,仍然提示上述错误,很明显,连接时,寻找函数出错了。
网上查的资料如下:
编译器不支持 模板类定义和实现的分离,即类定义和实现不能分开放在h头文件和cpp源码文件中;
经过测试,貌似把cpp文件的东西都搬到.h文件中,如果cpp文件还在,都还会提示该问题,所以,除了.h中放实现代码之外,还得把空的cpp文件删除。
从项目中删除后编译成功,但后来重新增加这个.cpp文件,貌似还是能编译成功。
上述的说法亲测正确,但仍有不足,补充资料留作记录:
首先C++中有分离编译的概念:
分离编译模式(Separate Compilation Model) 允许在一处翻译单元中定义(define)函数、类型、类对象等,在另一处翻译单元引用它们。编译器(Compiler)处理完所有翻译单元后,链接器(Linker)接下来处理所有指向 extern 符号的引用,从而生成单一可执行文件。该模式使得 C++ 代码编写得称心而优雅。
然而该模式却驯不服模板(Template)。标准要求编译器在实例化模板时必须在上下文中可以查看到其定义实体;而反过来,在看到实例化模板之前,编译器对模板的定义体是不处理的——原因很简单,编译器怎么会预先知道 typename 实参是什么呢?因此模板的实例化与定义体必须放到同一翻译单元中。
export关键字
标准 C++ 为此制定了“模板分离编译模式(Separation Model)”及 export 关键字。然而由于 template 语义本身的特殊性使得 export 在表现的时候性能很次。
用法此处就不说了,因为C++标准在11中将其丢弃了,所以不建议使用。
另外网上还有一些包含cpp文件的做法之类的,也不做介绍,我觉得不够规范化。因为模板的制定本身就是应该为实例化而开源。所以我比较赞同将模板类的定义和实现放在同一个文件的做法。
然后在test.cpp中测试,遇到了一些问题、
问题出现如下:
使用g++直接编译的时候提示,基本上都是undefined reference to错误:
test_binarytree.cpp:(.text+0x16e): undefined reference to `BinaryTree<std::string>::BinaryTree()' ......
分别编译单独文件,均可生成 .o文件,所以排除单个文件本身的错误
连接两个o文件时,仍然提示上述错误,很明显,连接时,寻找函数出错了。
网上查的资料如下:
编译器不支持 模板类定义和实现的分离,即类定义和实现不能分开放在h头文件和cpp源码文件中;
经过测试,貌似把cpp文件的东西都搬到.h文件中,如果cpp文件还在,都还会提示该问题,所以,除了.h中放实现代码之外,还得把空的cpp文件删除。
从项目中删除后编译成功,但后来重新增加这个.cpp文件,貌似还是能编译成功。
上述的说法亲测正确,但仍有不足,补充资料留作记录:
首先C++中有分离编译的概念:
分离编译模式(Separate Compilation Model) 允许在一处翻译单元中定义(define)函数、类型、类对象等,在另一处翻译单元引用它们。编译器(Compiler)处理完所有翻译单元后,链接器(Linker)接下来处理所有指向 extern 符号的引用,从而生成单一可执行文件。该模式使得 C++ 代码编写得称心而优雅。
然而该模式却驯不服模板(Template)。标准要求编译器在实例化模板时必须在上下文中可以查看到其定义实体;而反过来,在看到实例化模板之前,编译器对模板的定义体是不处理的——原因很简单,编译器怎么会预先知道 typename 实参是什么呢?因此模板的实例化与定义体必须放到同一翻译单元中。
export关键字
标准 C++ 为此制定了“模板分离编译模式(Separation Model)”及 export 关键字。然而由于 template 语义本身的特殊性使得 export 在表现的时候性能很次。
用法此处就不说了,因为C++标准在11中将其丢弃了,所以不建议使用。
另外网上还有一些包含cpp文件的做法之类的,也不做介绍,我觉得不够规范化。因为模板的制定本身就是应该为实例化而开源。所以我比较赞同将模板类的定义和实现放在同一个文件的做法。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 如何在 LibreOffice 中创建模板以实现省时高效
- 关于指针的一些事情
- 设计模式之行为型模式 - 调用行为的传递问题
- [div+css]晒晒最新制作专题推广页模板
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- 2008大学生入党申请书 模板
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- IMAIL多语言模板两套Outlook&Gmail模板下载
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结