如何定义一个模板类并将其分成多个文件?
我编写了一个简单的模板类用于测试目的。它编译时没有任何错误,但是当我尝试在 main() 中使用它时,它会给出一些链接器错误。
main.cpp
#include <iostream>
#include "MyNumber.h"
int wmain(int argc, wchar_t * argv[])
{
MyNumber<float> num;
num.SetValue(3.14);
std::cout << "My number is " << num.GetValue() << "." << std::endl;
system("pause");
return 0;
}
MyNumber.h
#pragma once
template <class T>
class MyNumber
{
public:
MyNumber();
~MyNumber();
void SetValue(T val);
T GetValue();
private:
T m_Number;
};
MyNumber.cpp
#include "MyNumber.h"
template <class T>
MyNumber<T>::MyNumber()
{
m_Number = static_cast<T>(0);
}
template <class T>
MyNumber<T>::~MyNumber()
{
}
template <class T>
void MyNumber<T>::SetValue(T val)
{
m_Number = val;
}
template <class T>
T MyNumber<T>::GetValue()
{
return m_Number;
}
当我构建此代码时,出现以下链接器错误:
错误 7 控制台演示 C:\Development\IDE\Visual Studio 2010\SAVE\Grand Solution\X64\Debug\Console Demo.exe 1 错误 LNK1120: 4 个无法解析的外部
错误 3 控制台演示 C:\Development\IDE\Visual Studio 2010\SAVE\Grand Solution\Console Demo\main.obj 错误 LNK2019:无法解析的外部符号“public: __cdecl MyNumber::~MyNumber(void)”(? ?1?$MyNumber@M@@QEAA@XZ) 在函数 wmain 中引用
错误 6 控制台演示 C:\Development\IDE\Visual Studio 2010\SAVE\Grand Solution\Console Demo\main.obj 错误 LNK2019: 无法解析的外部符号“public: __cdecl MyNumber::MyNumber(void)” (?? 0?$MyNumber@M@@QEAA@XZ) 在函数 wmain 中引用
错误 4 控制台演示 C:\Development\IDE\Visual Studio 2010\SAVE\Grand Solution\Console Demo\main.obj 错误 LNK2019:无法解析的外部符号“public: float __cdecl MyNumber::GetValue(void)”(? GetValue@?$MyNumber@M@@QEAAMXZ) 在函数 wmain 中引用
错误 5 控制台演示 C:\Development\IDE\Visual Studio 2010\SAVE\Grand Solution\Console Demo\main.obj 错误 LNK2019:无法解析的外部符号“public: void __cdecl MyNumber::SetValue(float)” (? SetValue@?$MyNumber@M@@QEAAXM@Z) 在函数 wmain 中引用
但是,如果我将 main() 留空,我不会没有出现任何链接器错误。
我的模板类有什么问题?
我做错了什么?
I have written a simple template class for test purpose. It compiles without any errors, but when I try to use it in main(), it give some linker errors.
main.cpp
#include <iostream>
#include "MyNumber.h"
int wmain(int argc, wchar_t * argv[])
{
MyNumber<float> num;
num.SetValue(3.14);
std::cout << "My number is " << num.GetValue() << "." << std::endl;
system("pause");
return 0;
}
MyNumber.h
#pragma once
template <class T>
class MyNumber
{
public:
MyNumber();
~MyNumber();
void SetValue(T val);
T GetValue();
private:
T m_Number;
};
MyNumber.cpp
#include "MyNumber.h"
template <class T>
MyNumber<T>::MyNumber()
{
m_Number = static_cast<T>(0);
}
template <class T>
MyNumber<T>::~MyNumber()
{
}
template <class T>
void MyNumber<T>::SetValue(T val)
{
m_Number = val;
}
template <class T>
T MyNumber<T>::GetValue()
{
return m_Number;
}
When I build this code, I get the following linker errors:
Error 7 Console Demo C:\Development\IDE\Visual Studio 2010\SAVE\Grand Solution\X64\Debug\Console Demo.exe 1 error LNK1120: 4 unresolved externals
Error 3 Console Demo C:\Development\IDE\Visual Studio 2010\SAVE\Grand Solution\Console Demo\main.obj error LNK2019: unresolved external symbol "public: __cdecl MyNumber::~MyNumber(void)" (??1?$MyNumber@M@@QEAA@XZ) referenced in function wmain
Error 6 Console Demo C:\Development\IDE\Visual Studio 2010\SAVE\Grand Solution\Console Demo\main.obj error LNK2019: unresolved external symbol "public: __cdecl MyNumber::MyNumber(void)" (??0?$MyNumber@M@@QEAA@XZ) referenced in function wmain
Error 4 Console Demo C:\Development\IDE\Visual Studio 2010\SAVE\Grand Solution\Console Demo\main.obj error LNK2019: unresolved external symbol "public: float __cdecl MyNumber::GetValue(void)" (?GetValue@?$MyNumber@M@@QEAAMXZ) referenced in function wmain
Error 5 Console Demo C:\Development\IDE\Visual Studio 2010\SAVE\Grand Solution\Console Demo\main.obj error LNK2019: unresolved external symbol "public: void __cdecl MyNumber::SetValue(float)" (?SetValue@?$MyNumber@M@@QEAAXM@Z) referenced in function wmain
But, if I leave main() empty, I don't get any linker errors.
What is wrong with my template class?
What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您必须为您使用的每个模板参数显式实例化您的模板。
即,在
MyNumber.cpp
文件末尾添加以下行:这样,链接器将能够找到它需要的所有模板实例化。
另请参阅将模板移出头文件。
You have to instantiate your template explicitly for each template parameter you use.
I.e., add the following line at the end of the
MyNumber.cpp
file:This way, the linker will be able to find all template instantiations it needs.
See also Moving Templates Out of Header Files.
您无法在 cpp 文件中实现该模板。您需要在头文件本身中定义类方法。请参阅此 为什么我不能将模板类的定义与它的声明并将其放入 .cpp 文件中? 了解更多信息。
You can not implement the template in a cpp file. You need to define the class methods in the header file itself. See this Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file? for more information.
好吧,您实际上应该能够使用 导出< /a> 关键字,但几乎没有编译器实现它。您可以通过将非通用代码提取到单独的函数中并在单独的文件中定义它们来解决此问题。
Well, you're actually supposed to be able to use the export keyword, but almost no compilers implement it. You can work around this by extracting non-generic code into separate functions, and define these in separate files.