2011-03-27 6 views
12

आज मेरा तीसरा प्रश्न ;-), लेकिन मैं सी ++ टेम्पलेट प्रोग्रामिंग और ऑपरेटर ओवरलोडिंग के लिए वास्तव में नया हूं।सी ++ टेम्पलेट विशेषज्ञता - लिंकर त्रुटि एकाधिक परिभाषाएं

मैं कोशिश कर रहा हूँ निम्नलिखित:

terminallog.hh

//snipped code 

class Terminallog { 
public: 

    Terminallog(); 
    Terminallog(int); 
    virtual ~Terminallog(); 

    template <class T> 
    Terminallog & operator<<(const T &v); 
    template <class T> 
    Terminallog & operator<<(const std::vector<T> &v); 
    template <class T> 
    Terminallog & operator<<(const T v[]); 
    Terminallog & operator<<(const char v[]); 

//snipped code 
}; 

//snipped code 
template <class T> 
Terminallog &Terminallog::operator<<(const T &v) { 
    std::cout << std::endl; 
    this->indent(); 
    std::cout << v; 
    return *this; 
} 

template <class T> 
Terminallog &Terminallog::operator<<(const std::vector<T> &v) { 
    for (unsigned int i = 0; i < v.size(); i++) { 
     std::cout << std::endl; 
     this->indent(); 
     std::cout << "Element " << i << ": " << v.at(i); 
    } 
    return *this; 
} 

template <class T> 
Terminallog &Terminallog::operator<<(const T v[]) { 
    unsigned int elements = sizeof (v)/sizeof (v[0]); 
    for (unsigned int i = 0; i < elements; i++) { 
     std::cout << std::endl; 
     this->indent(); 
     std::cout << "Element " << i << ": " << v[i]; 
    } 
    return *this; 
} 

Terminallog &Terminallog::operator<<(const char v[]) { 
    std::cout << std::endl; 
    this->indent(); 
    std::cout << v; 
    return *this; 
} 
//snipped code 

, यह मेरे एक लिंकर त्रुटि देता है इस कोड को संकलित करने के लिए कोशिश कर रहा है:

g++ src/terminallog.cc inc/terminallog.hh testmain.cpp -o test -Wall -Werror 
/tmp/ccifyOpr.o: In function `Terminallog::operator<<(char const*)': 
testmain.cpp:(.text+0x0): multiple definition of `Terminallog::operator<<(char const*)' 
/tmp/cccnEZlA.o:terminallog.cc:(.text+0x0): first defined here 
collect2: ld returned 1 exit status 

Therfore मैं वर्तमान में पीटने हूँ मेरी एक समाधान की खोज, दीवार के खिलाफ सिर। लेकिन मैं दीवार में एक नहीं मिल सकता है ...

यह अगर कोई मुझे मेरी गलती दिखा सकता है बहुत अच्छा होगा

बहुत बहुत

ftiaronsem

उत्तर

13

इस समारोह

धन्यवाद
Terminallog &Terminallog::operator<<(const char v[]) { 
    std::cout << std::endl; 
    this->indent(); 
    std::cout << v; 
    return *this; 
} 

एक टेम्पलेट नहीं है, लेकिन एक नियमित सदस्य समारोह है। यदि यह .h फ़ाइल कई .cpp filtes में शामिल है, तो यह आपके द्वारा देखे जा रहे एकाधिक परिभाषा त्रुटि का कारण बन जाएगा। यदि आप इसे inline घोषित करते हैं, तो संकलक एकाधिक परिभाषाओं की अनुमति देगा और आपकी त्रुटि को ठीक किया जाना चाहिए।

inline 
Terminallog &Terminallog::operator<<(const char v[]) { 
+0

वाह, बिल्कुल सही। बहुत बहुत धन्यवाद। लेकिन मेरे पास अभी भी एक सवाल है: मेरे पास उस हेडर फ़ाइल में गार्ड शामिल है। इसलिए इसे केवल एक बार शामिल किया जाना चाहिए। मुझे फिर भी यह त्रुटि क्यों मिल रही है? – ftiaronsem

+0

@fitaronsem: गार्ड को एक ही टीयू के भीतर _only_ कई परिभाषाओं के साथ मदद करें। आपकी त्रुटि एक _link_ त्रुटि है, संकलन त्रुटि नहीं; कई टीयू में कई परिभाषाएं होने पर गार्ड शामिल नहीं होते हैं। इसलिए, एक सामान्य नियम के रूप में, किसी शीर्षलेख में गैर-इनलाइन या गैर-टेम्पलेट फ़ंक्शन या चर परिभाषाएं न डालें। –

+0

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

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

  • कोई संबंधित समस्या नहीं^_^