Возможный дубликат:
Что такое неопределенная ссылка / неразрешенная внешняя ошибка символа и как ее исправить?
Поэтому я сравнил свою проблему с огромной библиотекой проблем, которые возникли из этой категории на этом сайте. Я до сих пор не понимаю, почему мой компилятор жалуется.
Итак, позвольте мне кратко рассказать о том, что я хочу делать с моей программой. Я исследую алгоритмы лифта. Я хочу реализовать приоритетные очереди, используя двоичную кучу.
Я получил исходный код с сайта Mark Allen Wiess. Для кучи.
Я создаю свой собственный класс reqnode, который представляет узлы двоичного дерева.
reqnode = узел запроса.
Сценарий таков: пользователь делает запрос. Я обслуживаю запрос. Я работаю с несколькими запросами. Таким образом, я должен использовать приоритет, который пользователь должен удовлетворить в первую очередь.
Это мой заголовочный файл для моей двоичной кучи.
#include <vector>
using namespace std;
BinaryHeap class.
CONSTRUCTION: with no parameters or vector containing items.
template <class Comparable>
class BinaryHeap
{
public:
BinaryHeap( );
BinaryHeap( const vector<int> & v );
bool isEmpty( ) const;
const Comparable & findMin( ) const;
void insert( const Comparable & x);
void deleteMin( );
void deleteMin( Comparable & minItem );
void makeEmpty( );
private:
int theSize; // Number of elements in heap
vector<Comparable> Array; // The heap Array
void buildHeap( );
void percolateDown( int hole );
};
Это функции, определенные для моей двоичной кучи.
#include "binaryHeap.h"using namespace std;
// Construct the binary heap.
template <class Comparable>
BinaryHeap<Comparable>::BinaryHeap( )
: Array( 11 ), theSize( 0 )
{
}
// Insert item x into the priority queue, maintaining heap order.
// Duplicates are allowed.template <class Comparable>
void BinaryHeap<Comparable>::insert( const Comparable & x)
{
Array[ 0 ] = x; // initialize sentinel
if( theSize + 1 == Array.size( ) )
Array.resize( Array.size( ) * 2 + 1 );
// Percolate up
int hole = ++theSize;
for( ; x < Array[ hole / 2 ]; hole /= 2 )
Array[ hole ] = Array[ hole / 2 ];
Array[ hole ] = x;
}
// Find the smallest item in the priority queue.
// Return the smallest item, or throw UnderflowException if empty.
template <class Comparable>
const Comparable & BinaryHeap<Comparable>::findMin( ) const
{
if( isEmpty( ) ){
cout << "heap empty" << endl; //throw UnderflowException( );
break;
}
return Array[ 1 ];
}
// Remove the smallest item from the priority queue.
// Throw UnderflowException if empty.
template <class Comparable>
void BinaryHeap<Comparable>::deleteMin( )
{
if( isEmpty( ) ){
cout << "heap empty" << endl; //throw UnderflowException( );
break;
}
Array[ 1 ] = Array[ theSize-- ];
percolateDown( 1 );
}
// Remove the smallest item from the priority queue
// and place it in minItem. Throw UnderflowException if empty.
template <class Comparable>
void BinaryHeap<Comparable>::deleteMin( Comparable & minItem )
{
minItem = findMin( );
Array[ 1 ] = Array[ theSize-- ];
percolateDown( 1 );
}
// Establish heap-order property from an arbitrary
// arrangement of items. Runs in linear time.
template <class Comparable>
void BinaryHeap<Comparable>::buildHeap( )
{
for( int i = theSize / 2; i > 0; i-- )
percolateDown( i );
}
// Test if the priority queue is logically empty.
// Return true if empty, false otherwise.
template <class Comparable>
bool BinaryHeap<Comparable>::isEmpty( ) const
{
return theSize == 0;
}
// Make the priority queue logically empty.
template <class Comparable>
void BinaryHeap<Comparable>::makeEmpty( )
{
theSize = 0;
}
// Internal method to percolate down in the heap.
// hole is the index at which the percolate begins.
template <class Comparable>
void BinaryHeap<Comparable>::percolateDown( int hole )
{
int child;
Comparable tmp = Array[ hole ];
for( ; hole * 2 <= theSize; hole = child )
{
child = hole * 2;
if( child != theSize && Array[ child + 1 ] < Array[ child ] )
child++;
if( Array[ child ] < tmp )
Array[ hole ] = Array[ child ];
else
break;
}
Array[ hole ] = tmp;
}
Это мой заголовочный файл для reQnode
class reqNode//create a node that takes in several properties.
{
public:
reqNode(){ //default constructor
static priority = start = destination = timestamp = start_time = finish_time = -1;
}
reqNode(const reqNode ©){ //copy constructor
priority = copy.priority;
start = copy.start;
destination = copy.destination;
timestamp = copy.timestamp;
start_time = copy.start_time;
finish_time = copy.finish_time;
}
reqNode & operator=(const reqNode & copy){
priority = copy.priority;
start = copy.start;
destination = copy.destination;
timestamp = copy.timestamp;
start_time = copy.start_time;
finish_time = copy.finish_time;
return *this;
}
int priority, start, destination, timestamp, start_time, finish_time;
bool direction;
bool operator<(reqNode &rhs){
if(this->priority < rhs.priority)
return true;
else
return false;
}
void setPriority(int x){
priority=x;
}
};
Это моя реализация драйвера
#include <iostream>
#include <fstream>
#include <string>
#include "binaryHeap.h"#include "reqnode.h"
#include <algorithm>
using namespace std;
void setNode(reqNode nizzode, int priority)
{
nizzode.priority = priority;
}int main()
{
int numItems = 10000;
BinaryHeap<reqNode> h;
int i = 37;
reqNode x;
reqNode * temp;
for( i = 37; i != 0; i = ( i + 37 ) % numItems ){
temp = new reqNode;
temp->setPriority(i);
h.insert( *temp );
}
for( i = 1; i < numItems; i++ )
{
h.deleteMin( x );
if( x.priority != i )
cout << "Oops! " << i << endl;
}
for( i = 37; i != 0; i = ( i + 37 ) % numItems ){
temp = new reqNode;
temp->setPriority(i);
h.insert( *temp );
}
temp = new reqNode;
temp->setPriority(i);
h.insert( *temp );return 0;
}
Наконец, это ошибки, которые преследуют меня!
1>Driver2.obj : error LNK2019: unresolved external symbol "public: void __thiscall BinaryHeap<class reqNode>::deleteMin(class reqNode &)" (?deleteMin@?$BinaryHeap@VreqNode@@@@QAEXAAVreqNode@@@Z) referenced in function _main
1>Driver2.obj : error LNK2019: unresolved external symbol "public: void __thiscall BinaryHeap<class reqNode>::insert(class reqNode const &)" (?insert@?$BinaryHeap@VreqNode@@@@QAEXABVreqNode@@@Z) referenced in function _main
1>Driver2.obj : error LNK2019: unresolved external symbol "public: __thiscall BinaryHeap<class reqNode>::BinaryHeap<class reqNode>(void)" (??0?$BinaryHeap@VreqNode@@@@QAE@XZ) referenced in function _main
1>C:\Users\Aaron Artis\Documents\Visual Studio 2010\Projects\Elevator_Algo_Remix1\Debug\Elevator_Algo_Remix1.exe : fatal error LNK1120: 3 unresolved externals
Я не уверен, где точно определить эту проблему. У меня была предыдущая ошибка компоновщика. Я решил это. Этот просто кажется глупым.
Не помещайте определения шаблонов в файл .CPP — они должны быть в файле .H, иначе компилятор не сможет их развернуть.
Возможно, вам даже не нужно BinaryHeap.c
Ваш компилятор жалуется, потому что он нашел декларации для конструктора функций, deleteMin
а также insert
, но нет определения.
Это связано с тем, что ваши определения должны быть в файле .cpp.
Помещение их непосредственно в файл binaryHeap.h после объявления класса решает проблему.
Подумайте об этом для шаблонных функций.
Похоже, что определение конструктора и два метода находятся в файле CPP; они должны быть в заголовочном файле.
Краткий ответ: Вы должны иметь свой BinaryHead<>
Объявление и определение в том же файле, так как это шаблон класса.
Длинный ответ: читать этот ответ Stackoverflow которые объясняют вещи в деталях.