2010-09-14 8 views
14

[[UPDATE]] -> Se I # include "Queue.cpp" nel mio programma.cpp, funziona perfettamente. Questo non dovrebbe essere necessario, giusto?C++ - Errore interno non risolto errore LNK2019 [costruttore e distruttore della classe modello di riferimento nella funzione _main

Ciao a tutti - Sto usando Visual Studio 2010 e ho problemi a collegare un'implementazione di coda rapida e sporca. Ho iniziato con un'applicazione vuota Console vuota e tutti i file sono presenti nel progetto. Per la verbosità, ecco il codice completo per duplicare il mio errore. Mi rendo conto che parte del codice potrebbe, in effetti, essere sbagliato. Non ho ancora avuto la possibilità di testarlo perché non sono ancora riuscito a collegarlo.

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; 
} 

E gli errori ...

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

Proprio come note generali sul codice; non è necessario includere guardie per ogni classe in un'intestazione, e farlo è molto più probabile che possa entrare in conflitto. Piuttosto, metti una guardia su tutto l'intestazione, in base al nome del file di quella intestazione. È una pratica standard e molto meno probabilità di imbattersi in altri nomi di file. –

+0

Duplicato di [Linker Error LNK2019] (http://stackoverflow.com/questions/3680312/linker-error-lnk2019) (Questa domanda viene richiesta circa cinque volte alla settimana) –

risposta

13

Perché non segui lo "Inclusion Model"? Ti consiglierei di seguire quel modello. Il compilatore deve avere accesso all'intera definizione del modello (non solo alla firma) per generare codice per ogni istanza del modello, quindi è necessario spostare le definizioni delle funzioni nell'intestazione.

Nota: in generale, la maggior parte dei compilatori C++ non supporta facilmente il modello di compilazione separato per i modelli.

Inoltre è necessario leggere this.

4

Gli errori del linker sono perché vedono i file di intestazione per Queue.hpp, ma non vedono le definizioni delle funzioni. Questo perché è una classe template, e per C++, le definizioni dei template devono essere nel file header (ci sono alcune altre opzioni, ma quella è la soluzione più semplice). Sposta le definizioni delle funzioni da Queue.cpp a Queue.hpp e dovrebbe essere compilato.

+0

Sì, tutti i file sono inclusi. Se, ad esempio, ometto un punto e virgola in Queue.cpp, il progetto non arriva al processo di collegamento perché improvvisamente non riesce a compilare. – Squirrelsama

+0

Non ho notato che era un modello durante il mio primo passaggio; questo spiega l'errore. –

+0

Perché i modelli causano questo errore? Inoltre ... [[UPDATE]] -> Se I # include "Queue.cpp" nel mio programma.cpp, funziona perfettamente. Questo non dovrebbe essere necessario, giusto? – Squirrelsama

4

Tutti i codici di modello devono essere accessibili durante la compilazione. Sposta i dettagli dell'implementazione di Queue.cpp nell'intestazione in modo che siano disponibili.

4

Se si dispone di:

template <typename T> 
void foo(); 

E fare:

foo<int>(); 

Il compilatore deve generare (istanze) in quella funzione. Ma non può farlo a meno che la definizione della funzione non sia visibile nel punto di istanziazione.

Ciò significa che le definizioni dei modelli devono essere incluse, in qualche modo, nell'intestazione. (È possibile includere il .cpp alla fine dell'intestazione, o semplicemente fornire le definizioni di linea.)

2

Un esempio per risolvere il LNK2019 errore:
Si devono scrivere #include "EXAMPLE.cpp" alla fine del .h di file

//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 
//---------------------------------------------- 

Nel file cpp fare come segue

//precompile header 
#include "stdafx.h" 
#pragma once 
#ifndef _EXAMPLE_CPP_ 
#define _EXAMPLE_CPP_ 

template <class T> 
void EXAMPLE<T>::Fnuction1() 
{ 
//codes 
} 

#endif 
//----------------------------------------------- 
Problemi correlati