使用模板,出现连接错unresolved external symbol ,VC6编译环境下

mmmcd 2008-01-27 02:02:05
如下程序,写在一个cpp里,编译没有问题

//#pragma once
template<class T> class TestClass
{
public:

TestClass();
TestClass(int height, int width);
~TestClass();
};

//在.cpp中定义:
//#include "TestClass.h"
template<class T>
TestClass<T>::TestClass()
{
}
template<class T>
TestClass<T>::TestClass(int height, int width)
{
}
template<class T>
TestClass<T>::~TestClass()
{
}
*/
//在测试Cpp中:
//#include "TestClass.h"

int main()
{
TestClass<int> array2d(10, 10);
return 0;
}


如果TestClass的定义分开写到TestClass.h,和TestClass.cpp中,将有下面错误

test.obj : error LNK2019: unresolved external symbol "public: __thiscall TestClass<int>::~TestClass<int>(void)" (??1?$TestClass@H@@QAE@XZ) referenced in function _main
test.obj : error LNK2019: unresolved external symbol "public: __thiscall TestClass<int>::TestClass<int>(int,int)" (??0?$TestClass@H@@QAE@HH@Z) referenced in function _main

vc6的问题还是程序问题?
如何解决?
...全文
509 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
tfzhy 2009-06-15
  • 打赏
  • 举报
回复
学习了,刚好遇到这种问题,困惑我好久了
ventry 2008-04-03
  • 打赏
  • 举报
回复
但是,由于模板具体实例化的特殊因素,导致编译器对分离模式的实现有巨大的复杂度,因而,分离模式至今未能获得大多数编译器的支持。所以在目前的编译环境下,请把模板的声明与定义全部放在.h文件中!否则,视不同的编译器,将会有不可预见的编译及链接错误生成。

很有道理,学习了,折腾我三个小时的问题终于搞定了,大家也应该体谅一下做编译器的不容易
kaien_kira 2008-03-05
  • 打赏
  • 举报
回复
太假了
实现都堆到H文件了
Linking...
Test.obj : error LNK2001: unresolved external symbol "public: void __thiscall List<int>::initList(void)" (?initList@?$List@H@@QAEXXZ)
Debug/List.exe : fatal error LNK1120: 1 unresolved externals
执行 link.exe 时出错.

List.exe - 1 error(s), 0 warning(s)

日阿~我搞了好半天了,原来是这里有问题啊~
fish6344 2008-01-31
  • 打赏
  • 举报
回复
Johnny_de朋友:

模板代码的组织模式,的确是C++标准有涉及的!最初,因编译器和链接器的实现原因以及包含模式的优势,进入标准的是包含模式,后因有很多的C++程序员的要求(关于包含模式与分离模式的优劣,争论至今仍未结束),C++标准导入关键字'export'以支持分离模式,但正如上所述,时至今日,只有很少的编译器与以支持(好象只有1个.)!

在程序设计层面,有一些技术可以有限的支持分离模式,例如把声明放在.h中,定义放在.cpp中,并在.h中使用#include,例如

//Template_h.h头文件:

#include"Template_h.cpp"//在如上头文件中声明的定义;

以及采用'explicit instantiation directive'明确具现一个定义体等方式,但如前述,这些方式都有局限性.所以当前,如果你需要你的模板代码具有良好的通用性(编译器的适应性),请使用模板代码组织的包含查式!
祥情请参考<<C++ Template The Complete Guide>>!
Johnny_de 2008-01-28
  • 打赏
  • 举报
回复
to # fish6344,你所说的类似于"模板代码的包含模式",这个是标准C++所涉及到的东西吗?
cut9 2008-01-28
  • 打赏
  • 举报
回复
我的拙见是,template 是编译期多态由编译器在编译期处理,所以这根本上限定了 template 的所有东西要在编译期 让编译器整一遍,不然编译器
不太明白(模板实例化,偏特化,,,,,,) 等。从某种意义上说,template 的出身就意味着这一点了。
fish6344 2008-01-27
  • 打赏
  • 举报
回复
不好意思,上述二文献的名字应更正为:

'在《C++ Primer》和《C++ Template The Complete Guide》中'
fish6344 2008-01-27
  • 打赏
  • 举报
回复
这是一个关于模板代码的组织问题,在《C++ Primer》和《C++标准程序库》中都有讨论。

如你先"如下程序,写在一个cpp里,编译没有问题",可以称为模板代码的包含模式(inclutions model)!这是目前所有编译器都支持的代码组织模式。

再如你所说:"TestClass的定义分开写到TestClass.h,和TestClass.cpp中....",即和通常一样,声明在.h中,定义在.cpp中,这称为分离模式!这是许多C++程序员所预期的一种代码组织模式.因此,C++标准专为此导入关键字'export'以支持模板代码组织的分离模式。

但是,由于模板具体实例化的特殊因素,导致编译器对分离模式的实现有巨大的复杂度,因而,分离模式至今未能获得大多数编译器的支持。所以在目前的编译环境下,请把模板的声明与定义全部放在.h文件中!否则,视不同的编译器,将会有不可预见的编译及链接错误生成。
我啃 2008-01-27
  • 打赏
  • 举报
回复
这个要把实现写在类定义里面,否则产生了链接实体在多个文件链接的时候产生多义错误。
关于“需要include cpp文件才能编译过”是你简单地把.cpp实现包括了进来
Johnny_de 2008-01-27
  • 打赏
  • 举报
回复
我还发现一个问题,即使能把实现写到cpp里,那么在测试程序中光引用头文件会报链接错误,需要include cpp文件才能编译过, very weird~~
我啃 2008-01-27
  • 打赏
  • 举报
回复
估计是编译器支持技术上的不足,否则~
Johnny_de 2008-01-27
  • 打赏
  • 举报
回复
我觉得太假了,难道说范型的推广要在某种程度上降低封装的基本原则? 这个可不是面向对象应该牺牲的东西哦.
silendream 2008-01-27
  • 打赏
  • 举报
回复
恩 我用的是VS2008 最新的
也是在模板这个问题上过不去。
它不支持export关键字 所以到后来还是得把它写在一个头文件里。
星羽 2008-01-27
  • 打赏
  • 举报
回复
现在的编译器几乎都不支持模板分离编,也就是不支持 export关键字

所以模板还是乖乖的全写在.h吧
Johnny_de 2008-01-27
  • 打赏
  • 举报
回复
我在VS2005下都有问题,如果我的函数没有涉及到参数,那么分开我就会有编译问题,写一起就没问题,涉及到参数的话分开就没有问题,我觉得很疑惑.
我啃 2008-01-27
  • 打赏
  • 举报
回复
VC6果然很废
  • 打赏
  • 举报
回复
目前VC6不支持模板分离编译,最新的VC9也不支持
将模板实现,写到.h文件里面吧
我啃 2008-01-27
  • 打赏
  • 举报
回复
简单的话就不要分开了,如果一定要分开,参考The C++ programming language 中分开编译那章里提及的对于模板类的实现,需要引入export关键字,详细的看看书就可以了
HelloDan 2008-01-27
  • 打赏
  • 举报
回复
模板不分开的一定行。
若你要分开,好像还有看你个人的编译器,但大多数都不支持分开的。
VC 6.0常见安装误 VC调试常见误 程序设计到多线程,VC++6.0默认设置可作以下修改: project->settings->C/C++->Category中选Code Generation->Use Run-time Library选Debug MultiThreaded或MultiThreaded 在创建MFC项目时, 不使用MFC AppWizard向导, 如果没有设置好项目参数, 就会在编译时产生很多连接误, 如error LNK2001误, 典型的误提示有: libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16 msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16 nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex 下面介绍解决的方法: 1. Windows子系统设置误, 提示: libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main Windows项目要使用Windows子系统, 而不是Console, 可以这样设置: [Project] --> [Settings] --> 选择"Link"属性页, 在Project Options中将/subsystem:console改成/subsystem:windows 2. Console子系统设置误, 提示: LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16 控制台项目要使用Console子系统, 而不是Windows, 设置: [Project] --> [Settings] --> 选择"Link"属性页, 在Project Options中将/subsystem:windows改成/subsystem:console 3. 程序入口设置误, 提示: msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16 通常, MFC项目的程序入口函数是WinMain, 如果编译项目的Unicode版本, 程序入口必须改为wWinMainCRTStartup, 所以需要重新设置程序入口: [Project] --> [Settings] --> 选择"C/C++"属性页, 在Category中选择Output, 再在Entry-point symbol中填入wWinMainCRTStartup, 即可 4. 线程运行时库设置误, 提示:

64,439

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧