如何定义一个模板类并将其分成多个文件?

发布于 2024-10-09 16:39:46 字数 2217 浏览 7 评论 0原文

我编写了一个简单的模板类用于测试目的。它编译时没有任何错误,但是当我尝试在 main() 中使用它时,它会给出一些链接器错误。


ma​​in.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

虚拟世界 2024-10-16 16:39:46

您必须为您使用的每个模板参数显式实例化您的模板。

即,在 MyNumber.cpp 文件末尾添加以下行:

template class MyNumber<float>;

这样,链接器将能够找到它需要的所有模板实例化。

另请参阅将模板移出头文件

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:

template class MyNumber<float>;

This way, the linker will be able to find all template instantiations it needs.

See also Moving Templates Out of Header Files.

机场等船 2024-10-16 16:39:46

您无法在 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.

帅冕 2024-10-16 16:39:46

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文