2015-09-15 8 views
6

मैं समान परिदृश्य है से चर/समारोह संघर्ष से बचने के:कैसे नीचे बताये गए सी में दो पुस्तकालयों ++

मेरे पास एक हेडर फाइल first.h यह एक समारोह है:

char* getName(); 

और संबद्ध cpp फ़ाइल first.cpp होने समारोह परिभाषा

char* getName(){return "first";} 

और second.h दूसरा हेडर फाइल यह है समारोह:

char* getName(); 

जुड़े cpp फ़ाइल second.cpp होने समारोह परिभाषा

char* getName(){return "second";} 

अब वहाँ एक main() समारोह है:

#include "first.h" 
#include "second.h" 

int main(){ 
return 0; 
} 

जब मैं उन .h फ़ाइलों में शामिल हैं, संकलक में एक त्रुटि देना फ़ंक्शन getName() क्योंकि यह विरोधाभासी है।

कैसे बदले बिना इस समस्या से छुटकारा पाने के .h files

+0

क्या फ़ंक्शन इनलाइन हैं, या असली शीर्षलेखों में केवल घोषणाएं हैं? यही कारण है कि मैं कभी समझ नहीं पा रहा हूं कि सी में नामस्थान क्यों नहीं हैं। टेम्पलेट्स और अधिभार के बिना, कुछ भी जटिल नहीं है, और वे सभी नामकरण विवादों को हल करेंगे और बेवकूफ उपसर्गों का अप्रचलित उपयोग प्रस्तुत करेंगे। – Jens

+0

क्या यह 'सी' या 'सी ++' है? सी ++ के लिए इस ट्यूटोरियल का उपयोग करें: http://www.tutorialspoint.com/cplusplus/cpp_namespaces.htm –

+0

सी में इन हेडर फ़ाइलों को बदले बिना आप इस स्थिति से छुटकारा नहीं पा सकते हैं। अगर आप हेडर फाइलों में से एक विधि को स्थिर मानते हैं इन विधियों के लिए C++ में नेमस्पेस संकलित या उपयोग करेगा। यदि आप शीर्षलेख फ़ाइलों में से किसी एक का उपयोग करना चाहते हैं और हेडर बदलना नहीं चाहते हैं, तो शीर्षलेख फ़ाइलों में से एक को शामिल करने के लिए #ifndef संरचना का उपयोग करें। –

उत्तर

5

आप जब उन हेडर फाइल सहित नामस्थान का उपयोग कर सकते हैं:

अपने cpp फ़ाइल में:

namespace first 
{ 
    #include "first.h" 
} 

namespace second 
{ 
    #include "second.h" 
} 

तो फिर तुम कार्यों का उपयोग कर सकते हैं निम्न के रूप में:

... 
first::getName(); 
second::getName(); 
... 

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

फ़ाइल आवरण-first.h:

namespace first 
{ 
    char* getName(); 
} 

फ़ाइल आवरण-पहले .cpp:

#include "wrapper-first.h" 
#include "first.h" 

char* first::getName() 
{ 
    return ::getName(); 
} 

... और दूसरी शीर्षलेख फ़ाइल के लिए इसे बनाएं। फिर आप अपनी सीपीपी फ़ाइल में wrpper-include फ़ाइलों को शामिल करते हैं और उपरोक्त कोड का उपयोग करते हैं।

+1

यह केवल तभी काम करता है जब फ़ंक्शन इनलाइन फ़ंक्शन हों। यदि शीर्षलेख केवल कार्यों की घोषणा करते हैं और कार्यान्वयन में जुड़ा हुआ है, तो यह काम नहीं करेगा। – Jens

+0

@ जेन्स यह अनाम नामों में भी होता है? (मुझे नहीं पता, बस पूछना)। –

+0

मैंने यह किया, अभी भी एक ही त्रुटि। –

3

यह मुश्किल होगा। पुस्तकालयों में getName प्रतीक होगा। लिंकर इसे प्रदान करने वाली पहली लाइब्रेरी का उपयोग करके getName प्रतीक को हल करेगा। यह पर पर ध्यान दिए बिना हेडर के साथ क्या होता है। आप बस भाग्यशाली हैं कि संकलक पहले ही शिकायत कर चुका है, और आपको एक स्पष्ट त्रुटि दी है।

थॉमस बार्डर का विचार संकलक समस्या को छिपाएगा। यह लिंकर समस्या को ठीक नहीं करेगा। first::getNameदूसरी लाइब्रेरी से ::getName का उपयोग करेगा, या इसके विपरीत।

आवश्यक समाधान first::getName है अपने लाइब्रेरी में। इस पुस्तकालय को केवल पहली पुस्तकालय के खिलाफ लिंक करना चाहिए। आपके सहायक पुस्तकालय और मूल द्वितीय पुस्तकालय के खिलाफ मुख्य निष्पादन योग्य लिंक। लिंकर में अब डुप्लिकेट प्रतीक नहीं हैं, क्योंकि इसे दो बार बुलाया जाता है। सहायक लाइब्रेरी का निर्माण करते समय, ::getName पहली लाइब्रेरी से अनजाने में आता है। मुख्य निष्पादन योग्य बनाते समय यह दूसरी पुस्तकालय से अनजाने में आता है।

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