Неопределенная ссылка на ‘Class & lt; Type & gt; :: Class’

Возможный дубликат:
Почему шаблоны могут быть реализованы только в заголовочном файле?

Я сталкивался с этой стеной раньше, но я не знаю, как ее починить. В g ++ я получаю эту ошибку всякий раз, когда пытаюсь создать объект класса BinaryTree:

/home/bej0843/cs261/Assignment1/main.cpp:9: undefined reference to `BinaryTree<char>::BinaryTree()'

Вот код для заголовочного файла:

#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <iostream>
#include <cstring>
#include <stack>
using namespace std;template<typename Type>
class BinaryTree
{
public:
struct TreeNode
{
Type nodeinfo;
BinaryTree<Type> *left;
BinaryTree<Type> *right;
};
BinaryTree();
void setInfo(Type a);
void setSubtree(Type a);
bool isEmpty();
Type Info();
void inOrder();
void preOrder();
void postOrder();
virtual ~BinaryTree();
protected:
TreeNode *root;
stack<TreeNode*> s;
stack<TreeNode*> temp;
private:
void postOrder(TreeNode *r);
};#endif  /* BINARYTREE_H */

А вот код для его реализации:

#include "BinaryTree.h"
template <typename Type>
BinaryTree<Type>::BinaryTree(){

root = NULL;
}

template <typename Type>
void BinaryTree<Type>::setInfo(Type a){
root->nodeinfo = a;
root->left = NULL;
root->right = NULL;
s.push(root);
}

template <typename Type>
void BinaryTree<Type>::setSubtree(Type a){
root->nodeinfo = a;
root->left->root = s.top();
s.pop();
root->right->root = s.top();
s.pop();
s.push(root);
}

template <typename Type>
bool BinaryTree<Type>::isEmpty(){
return (root==NULL);
}

template <typename Type>
Type BinaryTree<Type>::Info(){
return root->nodeinfo;
}

template <typename Type>
void BinaryTree<Type>::inOrder(){

TreeNode *c;
c = s.top();

while (c!=NULL || (!temp.empty())){
if (c!=NULL)
{
temp.push(c);
c = c->left;
}
else{
c = temp.top();
temp.pop();
cout << c->nodeinfo +" ";
c = c->right;
}
}

}

template <typename Type>
void BinaryTree<Type>::postOrder(){
postOrder(s.top());
}

template <typename Type>
void BinaryTree<Type>::postOrder(TreeNode *r){
temp.push(s.top());
TreeNode *c = temp.top();
s.pop();
postOrder(c->left->root);
postOrder(c->right->root);
cout << c->nodeinfo + " ";

}

template <typename Type>
void BinaryTree<Type>::preOrder(){
TreeNode*c = s.top();
while (c!=NULL||(!temp.empty())){
if (c!=NULL){
cout << c->nodeinfo + " ";
temp.push(c);
c=c->left;
}
else{
c=temp.top();
temp.pop();
c=c->right;
}
}
}

template <typename Type>
BinaryTree<Type>::~BinaryTree(){

}

В основном я звоню:

BinaryTree<char> tree;

и получите ошибку. Помогите?

0

Решение

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

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

Динамическое распределение в конструкторе класса шаблона

Вы можете сделать это так.

template <typename T>
class myClass
{
//public and private interface.
} ;

//Here the implementation of the interface goes, just beneath the declaration.
3

Другие решения

Когда вы пишете шаблонную функцию, как

template <typename Type>
BinaryTree<Type>::BinaryTree(){

root = NULL;
}

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

Вот почему нет BinaryTree<char>::BinaryTree(); компилятор никогда не генерировал код для этого! Причина в том, что ваш char экземпляр находится в отдельном модуле компиляции (объектный файл), из которого определена эта функция шаблона.

Чтобы это исправить, либо поместите main() функция в том же файле, который определяет все BinaryTreeфункции-члены, или поместите функции-члены в заголовочный файл, который объявляет класс.

1

Ошибка означает, что компоновщик не нашел определение конструктора для этого типа. Основная причина в шаблонном коде состоит в том, что определение функции (в данном случае — конструктор) недоступно в месте создания экземпляра, и не было выполнено явного создания экземпляра. Простое решение — предоставить определения шаблона в заголовке, чтобы сделать их доступными.

0
По вопросам рекламы [email protected]