2011-04-10 14 views
24

तो मैंने सुना है कि C++ टेम्पलेट्स एक ज और सीपीपी में अलग किया जाना चाहिए ...C++ टेम्पलेट और हेडर फाइल

उदाहरण के लिए इस तरह एक टेम्पलेट:

template <class T> 
class J{ 

    T something; 

} 

यह सच है ? ऐसा क्यों है?

यदि इसके कारण मुझे एक ही फ़ाइल में घोषणा और कार्यान्वयन दोनों रखना होगा, तो क्या मुझे इसे एक .h फ़ाइल या एक .cpp फ़ाइल में रखना चाहिए?

+0

एक उत्तर सी ++ पूछे जाने वाले प्रश्न में मौजूद है: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12 – birryree

उत्तर

23

शीर्षलेख।

ऐसा इसलिए है क्योंकि टेम्पलेट संकलन-समय पर नहीं, लिंक-टाइम और अलग-अलग अनुवाद इकाइयों (लगभग .cpp फ़ाइलों के बराबर) केवल एक दूसरे के लिंक-टाइम पर "जानते हैं" पर तत्काल होते हैं। शीर्षलेख संकलन-समय पर व्यापक रूप से "ज्ञात" होते हैं क्योंकि आप उन्हें #include किसी भी अनुवाद इकाई में उनकी आवश्यकता होती है।

https://isocpp.org/wiki/faq/templates और पढ़ें।

2

यदि आपको अन्य अनुवाद इकाइयों (.cpp फ़ाइलों) द्वारा उपयोग करने योग्य टेम्पलेट कोड की आवश्यकता है, तो आपको .h फ़ाइल में कार्यान्वयन करने की आवश्यकता है या अन्यथा वे इकाइयां टेम्पलेट को तुरंत चालू करने में सक्षम नहीं होंगी (विस्तार करें यह उनके द्वारा उपयोग किए जाने वाले प्रकारों के अनुसार)।

यदि आपका टेम्पलेट फ़ंक्शन केवल एक .cpp फ़ाइल में तत्काल है, तो आप इसे वहां परिभाषित कर सकते हैं। ऐसा कभी-कभी होता है जब किसी वर्ग के पास एक निजी सदस्य फ़ंक्शन होता है जो एक टेम्पलेट होता है (और इसे केवल कार्यान्वयन फ़ाइल से ही कहा जाता है, क्लास हेडर फ़ाइल नहीं)।

4

हाँ, यह सच है। घोषणापत्र और कार्यान्वयन आम तौर पर हेडर फ़ाइल में सभी को एक साथ रखा जाता है। कुछ कंपिलरों ने export कीवर्ड के साथ प्रयोग किया जो उन्हें अलग करने की अनुमति देगा, लेकिन इसे C++ 0x से हटा दिया गया है। सभी गंदे विवरणों के लिए this FAQ entry देखें।

12

कारण आप टेम्पलेट श्रेणी को एक .cpp फ़ाइल में नहीं डाल सकते हैं क्योंकि एक .cpp फ़ाइल को "संकलित" करने के लिए आपको यह जानने की आवश्यकता है कि टी के स्थान पर किस प्रकार का उपयोग किया जा रहा है। एक टेम्पलेटेड क्लास (जैसे आपकी कक्षा जे) में संकलन करने के लिए पर्याप्त जानकारी नहीं है। इस प्रकार यह सभी शीर्षकों में होना चाहिए।

यदि आप सफाई के लिए किसी अन्य फ़ाइल में कार्यान्वयन को तोड़ना चाहते हैं, तो सर्वोत्तम अभ्यास एक .hxx फ़ाइल का उपयोग करना है। इस तरह: अपने हेडर फाइल के अंदर, Jh, डाल:

#ifndef _J_H__ 
#define _J_H__ 

template <class T> class J{ // member definitions }; 

#include "j.hxx" 

#endif // _J_H__ 

और फिर, j.hxx में आपको मिलने वाले

template <class T> J<T>::J() { // constructor implementation } 

template <class T> J<T>::~J() { // destructor implementation } 

template <class T> void J<T>::memberFunc() { // memberFunc implementation } 

// etc. 
अंत में अपने .cpp फ़ाइल में

टेम्प्लेटेड वर्ग का उपयोग करता है, चलो चलो यह K.cpp फोन आप होगा:

#include "J.h" // note that this always automatically includes J.hxx  
void f(void) 
{ 
    J<double> jinstance; // now the compiler knows what the exact type is. 
} 
+2

मैं मैं '.hpp' एक्सटेंशन के उपयोग के बारे में निश्चित नहीं हूं। सम्मेलन से, सी ++ '.h' और '.hpp' में बहुत अधिक अदला-बदली जा सकती है, इसलिए आप' j.hpp' को एक फ़ाइल नाम के साथ नहीं बना रहे हैं जो इसे 'J.h' से कार्यात्मक रूप से अलग करता है। [यहां सम्मेलन 'J.hxx' होगा।] (Http://bytes.com/topic/c/answers/132004-inline-template-file-extensions) –

+0

+1 अच्छा बिंदु, और मैंने हमेशा उपयोग किया है अभ्यास में भी .xx (ज्यादातर दूसरों के उदाहरणों से सीखना), लेकिन मुझे कभी नहीं समझा कि यह अब तक सही क्यों था। –

+0

अगर मैं पूछूं, तो इसका क्या उपयोग है? अंत में, .h * या * यदि प्रत्येक # अंतर्निहित .cpp फ़ाइल को पुन: संकलित किया जाता है।hxx फ़ाइलें संशोधित हैं; और कार्यान्वयन को संशोधित करना जहां यह है। एच (यह उदाहरण नहीं; मेरा मतलब है कि जब पूरा टेम्पलेट .h में है) काफी समान होना चाहिए, यांत्रिक रूप से, नहीं? – Noein

संबंधित मुद्दे