Ошибка С++ - LNK2019 неразрешенный внешний символ [конструктор и деструктор класса шаблона], на который ссылается функция _main
[[UPDATE]] → Если я # включил "Queue.cpp" в свой файл program.cpp, он работает отлично. Это не обязательно, не так ли?
Привет всем - я использую Visual Studio 2010 и не могу связаться с быстрой и грязной реализацией очереди. Я начал с пустого консольного приложения Win32, и все файлы присутствуют в проекте. Для многословия здесь полный код для дублирования моей ошибки. Я понимаю, что некоторые из кода могут быть ошибочными. У меня еще не было возможности проверить его, потому что я еще не смог его связать.
Queue.hpp
#ifndef ERROR_CODE
#define ERROR_CODE
enum Error_Code
{
Success,
Underflow,
Overflow
};
#endif // ERROR_CODE
#ifndef QUEUE
#define QUEUE
template<class T>
struct Queue_Node
{
T data;
Queue_Node *next;
Queue_Node()
{
next = NULL;
}
Queue_Node(T pData)
{
data = pData;
next = NULL;
}
Queue_Node(T pData, Queue_Node *pNext)
{
data = pData;
next = pNext;
}
};
template<class T>
class Queue
{
public:
Queue();
Error_Code Serve();
Error_Code Append(T item);
T Front();
~Queue();
private:
void Rescursive_Destroy(Queue_Node<T> *entry);
Queue_Node<T> *front, *rear;
};
#endif // QUEUE
Queue.cpp
#include "Queue.hpp"
template <class T>
Queue<T>::Queue()
{
this->front = this->rear = NULL;
}
template<class T>
Error_Code Queue<T>::Serve()
{
if(front == NULL)
return Underflow;
Queue_Node *temp = this->front;
this->front = this->front->next;
delete temp;
}
template<class T>
Error_Code Queue<T>::Append(T item)
{
Queue_Node *temp = new Queue_Node(item);
if(!temp)
return Overflow;
if(this->rear != NULL)
this->rear->next = temp;
this->rear = temp;
return Success;
}
template<class T>
T Queue<T>::Front()
{
if(this->front == NULL)
return Underflow;
return this->front->data;
}
template<class T>
Queue<T>::~Queue()
{
this->Rescursive_Destroy(this->front);
}
template<class T>
void Queue<T>::Rescursive_Destroy(Queue_Node<T> *entry)
{
if(entry != NULL)
{
this->Recursive_Destroy(entry->next);
delete entry;
}
}
program.cpp
#include "Queue.hpp"
int main()
{
Queue<int> steve;
return 0;
}
И ошибки...
Error 1 error LNK2019: unresolved external symbol "public: __thiscall Queue<int>::~Queue<int>(void)" ([email protected]@@[email protected]) referenced in function _main C:\[omitted]\Project2_2\Project2_2\program.obj Project2_2
Error 2 error LNK2019: unresolved external symbol "public: __thiscall Queue<int>::Queue<int>(void)" ([email protected]@@[email protected]) referenced in function _main C:\[omitted]\Project2_2\Project2_2\program.obj Project2_2
Ответы
Ответ 1
Почему бы вам не следовать "Модель включения" ? Я бы рекомендовал вам следовать этой модели.
Компилятор должен иметь доступ ко всему определению шаблона (а не только к сигнатуре), чтобы генерировать код для каждого экземпляра шаблона, поэтому вам нужно переместить определения функций в свой заголовок.
Примечание. В большинстве случаев большинство компиляторов С++ не поддерживают отдельную модель компиляции для шаблонов.
Кроме того, вам необходимо прочитать .
Ответ 2
Ошибки компоновщика связаны с тем, что он видит файлы заголовков для Queue.hpp, но не видит определения функций. Это потому, что это класс шаблона, а для С++ определения шаблонов должны быть в файле заголовка (есть несколько других опций, но это самое простое решение). Переместите определения функций из Queue.cpp в Queue.hpp, и они должны скомпилироваться.
Ответ 3
Весь код шаблона должен быть доступен во время компиляции. Переместите детали реализации Queue.cpp в заголовок, чтобы они были доступны.
Ответ 4
Если у вас есть:
template <typename T>
void foo();
И вы делаете:
foo<int>();
Компилятор должен сгенерировать (создать экземпляр) эту функцию. Но это не может быть сделано, если определение функции не будет видно в момент создания экземпляра.
Это означает, что определение шаблонов должно быть каким-то образом включено в заголовок. (Вы можете включить .cpp
в конце заголовка или просто предоставить определения inline.)
Ответ 5
Пример для решения ошибки lnk2019:
Он должен написать #include "EXAMPLE.cpp" в конце файла .h
//header file codes
#pragma once
#ifndef EXAMPLE_H
#define EXAMPLE_H
template <class T>
class EXAMPLE
{
//class members
void Fnuction1();
};
//write this
#include "EXAMPLE.cpp"
#endif
//----------------------------------------------
В файле .cpp выполните следующие действия
//precompile header
#include "stdafx.h"
#pragma once
#ifndef _EXAMPLE_CPP_
#define _EXAMPLE_CPP_
template <class T>
void EXAMPLE<T>::Fnuction1()
{
//codes
}
#endif
//-----------------------------------------------