Как определить класс шаблона и разделить его на несколько файлов? - PullRequest
4 голосов
/ 24 декабря 2010

Я написал простой шаблонный класс для целей тестирования.Он компилируется без ошибок, но когда я пытаюсь использовать его в 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.exe1 ошибка LNK1120: 4 неразрешенных внешних кода

Ошибка 3 Демонстрация консоли C: \ Development \ IDE \ Visual Studio 2010 \ SAVE \ Grand Solution \ Демонстрация консоли \ 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 error LNK2019: неразрешенный внешний символ "public: __cdecl MyNumber :: MyNumber (void)" (?? 0? $ MyNumber @ M @@ QEAA @ XZ), на который есть ссылка в функции wmain

Ошибка 4 Console Demo C: \ Development \ IDE \ Visual Studio 2010 \ SAVE \ Grand Solution \ Console Demo \ main.obj error LNK2019: неразрешенный внешний символ "public: float __cdecl MyNumber :: GetValue (void)" (? GetValue@? $ MyNumber @ M @@ QEAAMXZ) ссылка на функцию wmain

Ошибка 5 Демонстрация консоли C: \ Development \ IDE \ Visual Studio 2010 \ SAVE \ Grand Solution \ Демонстрация консоли \ main.obj Ошибка LNK2019: неразрешенный внешний символ "public: void __cdecl MyNumber :: SetValue (float)"(? SetValue @? $ MyNumber @ M @@ QEAAXM @ Z) упоминается в функции wmain

Но, если я оставлю main () пустым, я не получу никаких ошибок компоновщика.

Что не так с моим классом шаблонов?
Что я делаю не так?

Ответы [ 3 ]

1 голос
/ 24 декабря 2010

Что ж, на самом деле вы должны иметь возможность использовать ключевое слово export , но компиляторы его почти не реализуют.Вы можете обойти это, извлекая неуниверсальный код в отдельные функции и определяя их в отдельных файлах.

1 голос
/ 20 ноября 2012

Вы должны создать экземпляр вашего шаблона явно для каждого используемого вами параметра шаблона.

Т.е. добавить следующую строку в конце файла MyNumber.cpp:

template class MyNumber<float>;

Таким образомкомпоновщик сможет найти все необходимые ему экземпляры шаблонов.

См. также Перемещение шаблонов из заголовочных файлов .

1 голос
/ 24 декабря 2010

Вы не можете внедрить шаблон в файл cpp.Вам нужно определить методы класса в самом заголовочном файле.Посмотрите это Почему я не могу отделить определение моего класса шаблонов от его объявления и поместить его в файл .cpp? для получения дополнительной информации.

...