2009-03-13 14 views
15

मैं एक समस्या मैं वास्तव में समझ में नहीं आता है नहीं मिल रहा। मेरे पास कक्षा नोड है।C++ टेम्पलेट के साथ वर्ग अपनी निर्माता

template<class T> 
class node { 
protected: 
    T _data; 
public: 
    node(T data); 
}; 

यह "node.h" फ़ाइल में है।

/usr/bin/ld:

#include "node.h" 

template<class T> 
node<T>::node (T data) { 
    _data = data; 
} 

संकलक कोई त्रुटि, लिंकर (LD) मुझसे कहता है पाता है जबकि: "node.cpp" फ़ाइल में, वहाँ इस निर्माता है: अपरिभाषित प्रतीक:

नोड < पूर्णांक > :: नोड (int)

अजीब हिस्सा ... यदि मैं कन्स्ट्रक्टर को .cpp से .h फ़ाइल में ले जाता हूं, तो सब कुछ ठीक काम करता है। समस्या कहाँ हे?

उत्तर

23

समस्या यह है कि टेम्पलेट्स कक्षाएं नहीं हैं - आप सामान्य रूप से दो अलग फ़ाइलों में उन्हें लिखना नहीं है। टेम्पलेट कक्षाएं कोड हैं जो संकलक पर कक्षाएं उत्पन्न करता है। इस प्रकार, आपके कार्यान्वयन कोड को हेडर में प्रभावी ढंग से इनलाइन करने की आवश्यकता है, यानी, जैसा आपने पाया है।

का पूरा विवरण दिया क्यों यह इस तरह से हो सकता है, C++ FAQ Lite देखना है के लिए

13

एक सामान्य नियम के रूप में, आप हेडर फाइल के अंदर सभी टेम्पलेट सदस्यों करना होगा। टेम्पलेट्स को एक प्रयोग के आधार पर संकलित किया जाता है, और इसलिए जहां भी उनका उपयोग किया जाता है, पूरी परिभाषा को उपलब्ध होने की आवश्यकता होती है। हेडर फ़ाइल में कोड डालने से उस समस्या का समाधान होगा।

केवल बार जब आप एक सीपीपी फ़ाइल में एक टेम्पलेट परिभाषा रख सकते हैं जब टेम्पलेट केवल कि सीपीपी फ़ाइल के भीतर इस्तेमाल किया जाएगा। कारण यह है कि यह मानक को पूरा करता है कि पूरी परिभाषा संकलन के लिए उपलब्ध है।

node.cpp की सामग्री को आगे बढ़ते node.h लिए समस्या ठीक कर देंगे।

अजीब परिदृश्य

फिर, यदि आप भी एक सीपीपी फ़ाइल में सब कुछ डाल दिया और सीपीपी फ़ाइल को शामिल कर सकते हैं। इस तरह से सी ++ लचीला है। मैं केवल इसका जिक्र करता हूं क्योंकि मैंने पहले किया है। जब मैंने अपनी मेज के शीर्ष पर मारा तो मैंने वास्तव में अपने जबड़े को कुचल दिया।

+1

तुम भी cpp फ़ाइल में एक गैर templatized वर्ग के templatized सदस्य कार्यों रख सकते हैं यदि आप कभी नहीं उन्हें कहीं और कॉल करने के लिए जा रहे हैं (ताकि इस लागू करने, वे निजी होना चाहिए, लेकिन उन्हें होना जरूरी नहीं है)। – rmeador

1

जब आप node<int> का उपयोग करते हैं, तो आपको सबसे अधिक संभावना node.cpp शामिल नहीं है। इसलिए संकलक node<int>::node<int> कन्स्ट्रक्टर को तुरंत चालू नहीं कर सकता है। आमतौर पर आप सभी टेम्पलेट कोड डालते हैं, जिसमें विधियों के सभी कार्यान्वयन, हेडर फ़ाइल में, या इसमें से कुछ शामिल है।

0

वहाँ फ़ंक्शन की कॉल जब तक, संकलक किसी भी कोड और लिंकर उत्पादन नहीं मिल नहीं करेगा।

आपको फ़ंक्शन को हेडर में रखना चाहिए जहां यह संबंधित है।

+0

मुझे अभी भी यह नहीं मिला है। टेम्पलेट अलग-अलग शीर्षलेख और स्रोत कोड के साथ कक्षा क्यों नहीं हो सकता है? मान लें कि मैं अपनी खुद की सूची लिखना चाहता हूं .. क्या मुझे हेडर फ़ाइल में प्रत्येक सूची विधि शामिल करना है? –

+0

हां, यह सबसे आम तरीका है। आप सूची.h के नीचे # List.cpp भी शामिल कर सकते हैं। –

+0

ठीक है तो। मुझे यह सब कुछ हेडर फ़ाइल में शामिल करने के लिए अजीब लगता है - वास्तविक कोड प्रश्न में कुछ पंक्तियों से थोड़ा लंबा है (यह एक बाइनरी खोज पेड़ है)। –

0

निहित इन्स्टेन्शियशन बंद कर दिया है, तो आप अपने कोड में

template class node<int>; 

कहीं जरूरत है (node.cpp शायद)

संपादित करें: बुरा जवाब, यह शायद ऐसा नहीं है।

+1

यदि आपको लगता है कि यह एक बुरा जवाब है, तो आप इसे कम करने से पहले इसे हटा सकते हैं। –

1

आमतौर पर स्वीकृत अभ्यास .h फ़ाइल में सभी कार्यान्वयन को रखना है, ताकि कक्षाओं को आवश्यकतानुसार टेम्पलेट से उत्पन्न किया जा सके।

यदि आप समय से पहले जानते हैं कि आपका टेम्पलेट किस प्रकार से चालू हो जाएगा, तो आप थोड़ा धोखा दे सकते हैं। बस सुनिश्चित करें कि आपके .cpp में प्रत्येक प्रकार और विधि की आवश्यकता होगी जिसके लिए आपको आवश्यकता होगी। यह महत्वपूर्ण है कि उपयोग केस टेम्पलेट कोड के बाद आते हैं। जैसे "Node.cpp" के लिए, का उपयोग

#include "node.h" 

template<class T> 
node<T>::node (T data) { 
    _data = data; 
} 

void dummy(void) 
{ 
    node<int> intnode(0); 
    node<double> doublenode(0.0); 
} 
1
// You can put templates declaration in header and definition in source 
// node.h or wherever you include file gets included 
extern template class node<int>; 

// node.cpp or where ever source file you want to use it 
// But use it only once for each type of generated class 
template class node<int>; 
संबंधित मुद्दे