2010-09-14 17 views
14

[[अद्यतन]] समारोह में संदर्भित -> अगर मैं अपने program.cpp में "Queue.cpp" # शामिल है, यह सिर्फ ठीक काम करता है। यह जरूरी नहीं होना चाहिए, है ना?सी ++ - LNK2019 त्रुटि अनसुलझे बाह्य प्रतीक [टेम्पलेट वर्ग के निर्माता और नाशक] _main

अरे सब - मैं दृश्य स्टूडियो 2010 का उपयोग कर रहा है और मुसीबत एक त्वरित और गंदा कतार कार्यान्वयन को जोड़ने है। मैं एक खाली Win32 कंसोल आवेदन के साथ शुरू किया, और सभी फ़ाइलों को परियोजना में मौजूद हैं। Verbosity के लिए, मेरी त्रुटि डुप्लिकेट करने के लिए यहां पूरा कोड है। मुझे एहसास है कि कुछ कोड वास्तव में गलत हो सकते हैं। मुझे अभी तक इसका परीक्षण करने का मौका नहीं मिला है क्योंकि मैं अभी तक इसे लिंक करने में सक्षम नहीं हूं।

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

निम्नलिखित ज फ़ाइल

//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 फ़ाइल में करते हैं; आपको हेडर में प्रत्येक वर्ग के लिए गार्ड शामिल करने की आवश्यकता नहीं है, और ऐसा करने से संघर्ष की संभावना अधिक होती है। इसके बजाय, उस हेडर के फ़ाइल नाम के आधार पर, पूरे हेडर के चारों ओर गार्ड को शामिल करें। यह मानक अभ्यास और अन्य फ़ाइल नामों में चलाने की बहुत कम संभावना है। –

+0

[लिंकर त्रुटि LNK2019] का डुप्लिकेट (http://stackoverflow.com/questions/3680312/linker-error-lnk2019) (यह प्रश्न हर सप्ताह पांच बार पूछता है) –

उत्तर

13

तुम क्यों "Inclusion Model" का पालन नहीं करते? मैं आपको उस मॉडल का पालन करने की सलाह दूंगा। टेम्पलेट के प्रत्येक तत्कालता के लिए कोड उत्पन्न करने के लिए कंपाइलर को संपूर्ण टेम्पलेट परिभाषा (केवल हस्ताक्षर नहीं) तक पहुंच की आवश्यकता है, इसलिए आपको कार्यों की परिभाषाओं को अपने शीर्षलेख में स्थानांतरित करने की आवश्यकता है।

नोट: सामान्य तौर पर सबसे सी ++ compilers आसानी से टेम्पलेट्स के लिए अलग संकलन मॉडल का समर्थन नहीं करते।

इसके अलावा आप this.

4

लिंकर त्रुटियां हैं क्योंकि यह Queue.hpp के लिए हेडर फ़ाइलों को देखती है, लेकिन कार्यों की परिभाषाओं को नहीं देखती है। ऐसा इसलिए है क्योंकि यह एक टेम्पलेट वर्ग है, और सी ++ के लिए, टेम्पलेट की परिभाषा हेडर फ़ाइल में होनी चाहिए (कुछ अन्य विकल्प हैं, लेकिन यह सबसे आसान समाधान है)। Queue.cpp से Queue.hpp तक फ़ंक्शंस के परिभाषाओं को ले जाएं और इसे संकलित करना चाहिए।

+0

हां, सभी फाइलें शामिल हैं। यदि मैं, उदाहरण के लिए, Queue.cpp में अर्धविराम छोड़ देता हूं, तो प्रोजेक्ट लिंकिंग प्रक्रिया में नहीं आता है क्योंकि यह अचानक संकलन करने में विफल रहता है। – Squirrelsama

+0

मुझे नहीं पता था कि यह मेरे पहले पास के दौरान एक टेम्पलेट था; जो त्रुटि बताता है। –

+0

टेम्पलेट्स इस त्रुटि का कारण क्यों बनाते हैं? इसके अलावा ... [[अद्यतन]] -> यदि मैं अपने प्रोग्राम.cpp में "Queue.cpp" शामिल करता हूं, तो यह ठीक काम करता है। यह जरूरी नहीं होना चाहिए, है ना? – Squirrelsama

4

सभी टेम्पलेट कोड संकलन के दौरान सुलभ होना चाहिए। Queue.cpp कार्यान्वयन विवरण शीर्षलेख में ले जाएं ताकि वे उपलब्ध हों।

4

पढ़ने की जरूरत है यदि आपके पास:

template <typename T> 
void foo(); 

और आप कार्य करें:

foo<int>(); 

संकलक उत्पन्न करने के लिए (इन्स्तांत) कि समारोह की जरूरत है। लेकिन यह तब तक नहीं कर सकता जब तक कि फ़ंक्शन परिभाषा तत्काल के बिंदु पर दिखाई दे।

इसका मतलब है कि किसी भी तरह से, शीर्षलेख में टेम्पलेट परिभाषाओं को शामिल करने की आवश्यकता है। (आप शीर्ष लेख के अंत में .cpp शामिल कर सकते हैं, या बस इनलाइन परिभाषा प्रदान करते हैं।)

2

त्रुटि lnk2019 को सुलझाने के लिए एक उदाहरण:
यह के अंत में #include "EXAMPLE.cpp" लिखने के लिए है ।के रूप में

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

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

#endif 
//----------------------------------------------- 
बस कोड पर सामान्य नोटों के रूप में
संबंधित मुद्दे