C++中模板不能把实现和声明放在两个不同的文件下
2013-02-06 09:46
726 查看
http://zhidao.baidu.com/question/322405048.html
http://www.zhihu.com/question/20630104
http://bbs.chinaunix.net/thread-923716-1-1.html
两个解决方案:
①将Fraction.h和Fraction.cpp文件写到一个文件中,即Fraction.h头文件。
②将Fraction.cpp改名为Fraction.template文件,然后再Fraction.h倒数第一行#endif之前加入一行代码 #include "Fraction.template"即可。
谢@欲三更 邀,这个问题让我想起我在实习的时候犯的一个错误,就是把模版类的定义和实现分开写了,结果编译出错,查了两天才查出问题。
C++
中每一个对象所占用的空间大小,是在编译的时候就确定的,在模板类没有真正的被使用之前,编译器是无法知道,模板类中使用模板类型的对象的所占用的空间的
大小的。只有模板被真正使用的时候,编译器才知道,模板套用的是什么类型,应该分配多少空间。这也就是模板类为什么只是称之为模板,而不是泛型的缘故。
既
然是在编译的时候,根据套用的不同类型进行编译,那么,套用不同类型的模板类实际上就是两个不同的类型,也就是说,stack<int>和
stack<char>是两个不同的数据类型,他们共同的成员函数也不是同一个函数,只不过具有相似的功能罢了。
如
上图所示,很简短的六行代码,用的是STL里面的stack,stack<int>和stack<char>的默认构造函数和
push函数的入口地址是不一样的,而不同的stack<int>对象相同的函数入口地址是一样的,这个也反映了模板类在套用不同类型以后,
会被编译出不同代码的现象。
所以模板类的实现,脱离具体的使用,是无法单独的编译的;把声明和实现分开的做法也是不可取的,必须把实现全部写在头文件里面。为了清晰,实现可以不写在class后面的花括号里面,可以写在class的外面。
另外提供一些参考:
http://stackoverflow.com/questions/1724036/splitting-templated-c-classes-into-hpp-cpp-files-is-it-possible
目前大部分的C++编译器要求把模版的定义和实现都放在头文件中,而不能支持分开编译的方式。
C++标准中有一个export关键来解决这个问题,但现在大部份的编译器并不能支持它。
http://www.zhihu.com/question/20630104
http://bbs.chinaunix.net/thread-923716-1-1.html
在Fraction.h中,我是这么定义的 #pragma once #ifndef FRACTION #define FRACTION template<class T> class Fraction { public: Fraction(void); Fraction(T ,T); ~Fraction(void); private: T numerator;//分子 T denominator;//分母 }; #endif 在Fraction.cpp中我是这么实现的 #include "StdAfx.h" #include "Fraction.h" template<class T> Fraction<T>::Fraction(void):numerator(0),denominator(0) { } template<class T> Fraction<T>::Fraction(T numerator,T denominator) { this->numerator=numerator;//分子 this->denominator=denominator;//分母 } template<class T> Fraction<T>::~Fraction(void) { } 主函数调用如下 #include "stdafx.h" #include"Fraction.h" int _tmain(int argc, _TCHAR* argv[]) { Fraction<int> ftion(10,120); return 0; } 提示如下错误 1>One.obj : error LNK2019: unresolved external symbol "public: __thiscall Fraction<int>::~Fraction<int>(void)" (??1?$Fraction@H@@QAE@XZ) referenced in function _wmain 1>One.obj : error LNK2019: unresolved external symbol "public: __thiscall Fraction<int>::Fraction<int>(int,int)" (??0?$Fraction@H@@QAE@HH@Z) referenced in function _wmain 1>F:\DataStruct\ChapterOne\One\Debug\One.exe : fatal error LNK1120: 2 unresolved externals 1>Build log was saved at "file://f:\DataStruct\ChapterOne\One\One\Debug\BuildLog.htm" 1>One - 3 error(s), 0 warning(s)
两个解决方案:
①将Fraction.h和Fraction.cpp文件写到一个文件中,即Fraction.h头文件。
②将Fraction.cpp改名为Fraction.template文件,然后再Fraction.h倒数第一行#endif之前加入一行代码 #include "Fraction.template"即可。
这个是初学者常见问题了。 简而言之,目前绝大多数C++编译器不支持将模版类/模版函数的声明与实现分开。 所以你要写就全部一起写在头文件中,不要分开写到两个文件中。或者像楼上所说在头文件中再#include一次(不过没啥意义)。 这个是C++的一个老顽固问题了,虽然C++标准有规定通过export关键字来实现模版的分离编译,但是因为实现过于复杂,实际上几乎没有编译器鸟它。VC、BC、GCC都不支持。(貌似只有ICC部分支持) 所以你也只能向现实妥协了呵呵,就像STL一样,把模版函数和模版类的实现全部写在.h头文件中吧。
谢@欲三更 邀,这个问题让我想起我在实习的时候犯的一个错误,就是把模版类的定义和实现分开写了,结果编译出错,查了两天才查出问题。
C++
中每一个对象所占用的空间大小,是在编译的时候就确定的,在模板类没有真正的被使用之前,编译器是无法知道,模板类中使用模板类型的对象的所占用的空间的
大小的。只有模板被真正使用的时候,编译器才知道,模板套用的是什么类型,应该分配多少空间。这也就是模板类为什么只是称之为模板,而不是泛型的缘故。
既
然是在编译的时候,根据套用的不同类型进行编译,那么,套用不同类型的模板类实际上就是两个不同的类型,也就是说,stack<int>和
stack<char>是两个不同的数据类型,他们共同的成员函数也不是同一个函数,只不过具有相似的功能罢了。
如
上图所示,很简短的六行代码,用的是STL里面的stack,stack<int>和stack<char>的默认构造函数和
push函数的入口地址是不一样的,而不同的stack<int>对象相同的函数入口地址是一样的,这个也反映了模板类在套用不同类型以后,
会被编译出不同代码的现象。
所以模板类的实现,脱离具体的使用,是无法单独的编译的;把声明和实现分开的做法也是不可取的,必须把实现全部写在头文件里面。为了清晰,实现可以不写在class后面的花括号里面,可以写在class的外面。
另外提供一些参考:
http://stackoverflow.com/questions/1724036/splitting-templated-c-classes-into-hpp-cpp-files-is-it-possible
目前大部分的C++编译器要求把模版的定义和实现都放在头文件中,而不能支持分开编译的方式。
C++标准中有一个export关键来解决这个问题,但现在大部份的编译器并不能支持它。
相关文章推荐
- C++中模板的声明和实现应该放在同一个文件中
- C++-模板的声明和实现为何要放在头文件中
- C++第六周任务5:解决用一个项目多个文件的方式实现,其中两个类的声明放在一个.h文件中,每个类的成员函数分别放一个文件,main()函数用一个文件。体会这样安排的优点。
- 模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 学习笔记之C++为什么将函数声明或者类的定义放在.h文件中,而将其实现放在原文件中
- 模板的声明和实现为何要放在头文件中?
- C++的类模板的问题(实现文件和头文件放在一起), 因为模板不支持分离编译
- C++模板声明和实现为什么不能分开来写
- 将任务4的解决用一个项目多个文件的方式实现,其中两个类的声明放在一个.h文件中,每个类的成员函数分别放一个文件,main()函数用一个文件。
- 转贴:模板的声明和实现为何要放在头文件中?
- C++中模板定义与声明为什么放在同一个文件中
- 模板的声明和实现为何要放在头文件中?
- 模板的声明和实现为何要放在头文件中?
- 模板函数的声明和定义为何不能分开放在两个文件中?
- 模板的声明和实现为何要放在头文件中?
- 读《模板的声明和实现为何要放在头文件中?》有感
- 模板的声明和实现为何要放在头文件中?