Пишу класс для работы с матрицами. Определения функций расположены в файле MyMatrix.h, реализация в MyMatrix.cpp, функция main в файле test.cpp. MyMatrix.h
#include <iostream>
using namespace std;
template <class T>
class MyMatrix
{
private:
T **contents;
int rows;
int cols;
public:
MyMatrix(void);
~MyMatrix(void);
friend ostream& operator<<(ostream& os, const MyMatrix & m);
};
#include <iostream>
#include"MyMatrix.h"using namespace std;
int main()
{
MyMatrix<int> m;
return 0;
}
При этом возникает ошибка: "error LNK2019: unresolved external symbol "public: __thiscall MyMatrix<int>::MyMatrix<int>(void)"".
Почему линкер не может найти определение конструктора?
Проблема в том, что компиляторы не умеют работать с внешними шаблонами, шаблонами которые определены в другой единице трансляции. Решение перенести определение конструкторов и деструкторов из mymatrix.cpp в хедер.
Здравствуйте, av239, Вы писали:
A>При этом возникает ошибка: "error LNK2019: unresolved external symbol "public: __thiscall MyMatrix<int>::MyMatrix<int>(void)"". A>Почему линкер не может найти определение конструктора?
Я думаю у компилятора не получается отдельно откомпилировать шаблонный код, не зная заранее аргумента шаблона. Для этого нужно использовать такую возмжность языка как экспорт шаблонов, но она далеко не везде поддерживается. Проще поместить в заголовочный всю реализацию шаблона.
Здравствуйте, av239, Вы писали:
A>Спасибо, помогло. Получается что советы вроде интерфейс должен быть в заголовочном файле а реализация в сишном не работают при использовании шаблонов?
Можно включить MyMatrix.cpp в конец файла MyMatrix.h, напрямую или с помощью include.
Компилятор будет обрабатывать файл MyMatrix.cpp как заголовок.
Здравствуйте, av239, Вы писали:
A>Пишу класс для работы с матрицами. Определения функций расположены в файле MyMatrix.h, реализация в MyMatrix.cpp, функция main в файле test.cpp. A>MyMatrix.h
A>MyMatrix.cpp
A>test.cpp
A>При этом возникает ошибка: "error LNK2019: unresolved external symbol "public: __thiscall MyMatrix<int>::MyMatrix<int>(void)"". A>Почему линкер не может найти определение конструктора?
Проблема в инстанцировании шаблона. Инстанцирование шаблона – это генерация кода функции или класса по шаблону для конкретных параметров. Инстанцирование можно делать только в точке программы, где доступна реализация шаблона функции или методов шаблонного класса.
Отсюда, для вас два пути :
1) Использовать неявное инстанцирование (как вам уже ответил аноним), т.е. поместить реализацию в заголовочный файл. Когда компилятор встретит использование конкретного параметра, он сгенерирует нужный код класса MyMatrix.
2) Если же хочется реализацию скрыть, то нужно использовать явное инстанцирование, т.е. перечислить все типы, которые будут использоваться в программе в шаблоне MyMatrix. То есть добавить в файл с реализацией следующие строки:
MyMatrix.cpp
//...template class MyMatrix<int>;
template class MyMatrix<double>;
...
30.05.2011 19:20, av239 пишет:
> Пишу класс для работы с матрицами. Определения функций расположены в > файле MyMatrix.h, реализация в MyMatrix.cpp, функция main в файле test.cpp.
А зачем ты его пишешь?
При условии, что выглядит, уже то, что ты написал не очень.
Здравствуйте, av239, Вы писали:
A>Спасибо, помогло. Получается что советы вроде интерфейс должен быть в заголовочном файле а реализация в сишном не работают при использовании шаблонов?
Для шаблонов, которые инстанцируются всего 2-3 типами, обычно удобнее написать