Проблема класса шаблона C ++ - PullRequest
1 голос
/ 04 июля 2011

Привет всем, я просто хотел попрактиковаться в некотором шаблоне c ++, но я получаю ошибки компоновщика. Кто-нибудь может мне помочь, пожалуйста? Вот мой код:

// File: MyClass.h
#ifndef _MYCLASS_H
#define _MYCLASS_H
template<class T> class MyClass {
T value;
public:
MyClass(T v);
~MyClass();
};
#endif // _MYCLASS_H

// File: MyClass.cpp
#include "MyClass.h"
template<class T> MyClass<T>::MyClass(T v) {
value = v;
}
template<class T> MyClass<T>::~MyClass() {

}

// File: main.cpp
#include "MyClass.h"
int main() {
MyClass<int> test(10);
return 0;
}

Вот вывод командной строки:

g++ main.cpp -c
g++ MyClass.cpp -c
g++ main.o MyClass.o -o Out
main.o: In function `main':
main.cpp:(.text+0x1a): undefined reference to `MyClass<int>::MyClass(int)'
main.cpp:(.text+0x2b): undefined reference to `MyClass<int>::~MyClass()'
collect2: ld returned 1 exit status
make: *** [all] Error 1

Как видите, я использую Ubuntu 10.04 и GNU C ++ Compiler. Я что-то упустил в этом коде?


Спасибо за ответы. Это работает, но разве нет лучшего способа защитить код? Например, что если я хочу создать библиотеку без открытых источников ?! Я хочу экспортировать код в статическую библиотеку. и связать библиотеку с другими проектами ...

Ответы [ 4 ]

5 голосов
/ 04 июля 2011

Вы должны поместить полный шаблон в шапку.Компилятор должен видеть тело методов шаблона на сайте создания шаблона - main.cpp в вашем случае.См., Например, C ++ FAQ .

1 голос
/ 04 июля 2011

@ Николай Фетисов имеет правильное решение. Я хотел бы добавить к этому, что хороший способ сделать это, если вы хотите сохранить реализацию и шаблонные определения функций отдельно, это то, что вы можете поместить реализации в MyClass.hxx и включить их в конце вашего MyClass.h

// File: MyClass.h 
#ifndef _MYCLASS_H 
#define _MYCLASS_H 

template<class T> class MyClass 
{ 
  T value; 
public: 
  MyClass(T v);
  ~MyClass(); 
}; 

#include "MyClass.hxx"   /// <--- like this
#endif // _MYCLASS_H 
1 голос
/ 04 июля 2011

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

0 голосов
/ 04 июля 2011

Важно помнить, что такое шаблон.Это шаблон для генерации кода, если это необходимо;это не сам код.

Таким образом, объявление класса шаблона и написание реализаций для этих методов не генерирует никакого объектного кода для этого класса;при необходимости он просто предоставляет шаблон для этого.

Когда экземпляр класса шаблона создается с фактическим аргументом, компилятор сгенерирует код из класса шаблона.Для этого он должен иметь возможность видеть шаблоны.Но так как вы только #include отредактировали файл .h и реализацию методов в файле .cpp, компилятор не сможет сгенерировать объектный код для реализаций функций.Затем, когда компоновщик ищет эти определения, он не находит его.

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

...