2013-09-18 3 views
6

У меня возникла проблема с созданием объекта класса из класса шаблона, в котором мне нужен конструктор, который также должен быть шаблоном и принимать параметр при создании объекта. Однако, когда я пытаюсь создать объект, я получаю сообщение об ошибке, в котором говорится, что я ссылаюсь на то, что не существует.Создание объекта класса шаблона с использованием конструктора шаблона

Вот мой код:

using namespace std; 
#include <cstdlib> 

template <class Node_Type> 
class BinaryTree 
{ 
public: 
    BinaryTree(Node_Type); 
    BinaryTree(Node_Type, Node_Type); 
    BinaryTree(Node_Type, Node_Type, Node_Type); 
    bool isEmpty(); 
    Node_Type info(); 
    Node_Type inOrder(); 
    Node_Type preOrder(); 
    Node_Type postOrder(); 


private: 
    struct Tree_Node 
{ 
    Node_Type Node_Info; 
    BinaryTree<Node_Type> *left; 
    BinaryTree<Node_Type> *right; 
}; 

Tree_Node *root; 

}; 

#endif 

и мой .cpp:

template <class Node_Type> 
BinaryTree<Node_Type>::BinaryTree(Node_Type rootNode) { 

    root = rootNode; 
    root->left = NULL; 
    root->right = NULL; 

} 

Там больше к .cpp, но это просто другие члены функции, которые не имеют значения. Мой конструктор, показанный выше, я не могу заставить работать.

В моей основной, я пытаюсь объявить свой объект с вызовом:

BinaryTree<char> node('a'); 

, но когда я пытаюсь это, я получаю сообщение об ошибке:

undefined reference to `BinaryTree<char>::BinaryTree(char)' 

Я пытался понять это уже два дня. Я искал каждую тему, о которой я могу думать, и читаю бесчисленные примеры в Stack Overflow и других источниках без какой-либо помощи. Может кто-нибудь объяснить, что моя проблема? Я знаю, как сделать свой проект, и я бы закончил, если бы синтаксис не был настолько смешным в C++. Заранее спасибо!

+1

Ответ на вашу проблему - это именно то, о чем компилятор вам говорит. 'Tree_Node *' is * not * a 'char'. – WhozCraig

+1

Короткий и неточный: потому что у вас есть тело вашей функции, которое зависит от шаблона внутри файла '.cpp'. Он должен быть с вашим файлом '.h' либо непосредственно в вашем определении класса, либо если вам не нравится размещать его там, потому что для его упрощения читать, объявлять функцию как' inline' и перемещать ее за пределы класса определение, либо в том же файле, либо в '.hpp', который вы включаете в' .h' –

+0

@WhozCraig является правильным 'root' имеет тип' Tree_Node * 'не' char' – loki

ответ

10

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

6

Решение: Вы не можете отделять реализации шаблонов от файла заголовка. Просто не используйте файл cpp и поместите определение в свой файл заголовка (файл .h).

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

+1

Хотя это правильное утверждение, широко рассматривается [в этом вопросе ] (http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file), и в конечном итоге это будет проблемой независимо, это * не * ответ на вопрос OP о получении конкретного сообщения об ошибке. – WhozCraig

+1

@WhozCraig Вы уверены? r, похоже, жалуется, что конструктор не определен, а не то, что конструктор плохо определен. –

+1

@AlanStokes Фактически, его * оба *, но вы правы, и я пошлю Самеру соответственно вверх (на самом деле все трое). Код OP должен будет сильно изменяться независимо от того, пока он окончательно функционирует. Спасибо, что указали это. Я неправильно прочитал исходное сообщение об ошибке. – WhozCraig

2

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

BinaryTree<char>; 
BinaryTree<int>; 
BinaryTree<double>; 

Таким образом, все функции не обязательно должны быть в заголовочных файлах. Некоторые люди используют расширение .inl для файлов с реализациями шаблонов. Поэтому файл .inl нужен только тогда, когда экземпляр не существует.

Смежные вопросы