简体   繁体   中英

How do I define a template class and divide it into multiple files?

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?

You have to instantiate your template explicitly for each template parameter you use.

Ie, 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 .

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM