2010-09-10 14 views
5

एक ही नाम के साथ हेडर फ़ाइल को शामिल करके आप कैसे हल करते हैं जैसे किसी अन्य शीर्षलेख फ़ाइल को पहले से अप्रत्यक्ष रूप से किसी दूसरे के परिणामस्वरूप शामिल किया गया है?सी ++: अलग-अलग नामस्थानों से एक ही नाम के साथ एकाधिक शीर्षलेख फ़ाइलों को शामिल करें

उदाहरण के लिए:

// src/blah/a.hpp 
#ifndef A_HPP 
#define A_HPP 

namspace blah 
{ 

class A 
{ 
} 

} 

#endif 

// src/blah/b.hpp 
#ifndef B_HPP 
#define B_HPP 

#includes "a.hpp" 

namspace blah 
{ 

class B 
{ 
} 

} 

#endif 

// src/foo/a.hpp 
#ifndef A_HPP 
#define A_HPP 

namspace foo 
{ 

class A 
{ 
} 

} 

#endif 

// src/foo/c.hpp 
#ifndef C_HPP 
#define C_HPP 

#includes "../b.hpp" 
#includes "a.hpp"  // won't be included due to multiple inclusion prevention 

namspace foo 
{ 

class C 
{ 
} 

} 

#endif 

पिछले हेडर फाइल में, a.hpp क्योंकि शामिल किए जाने के पूर्वप्रक्रमक गार्ड शामिल नहीं किया जाएगा। वास्तव में, यह ठीक होना चाहिए हालांकि कक्षाएं अलग-अलग नामस्थानों में हैं। मुझे एहसास है कि आसान तरीका है foo/a.hpp का नाम बदलना या इसे एकाधिक समावेशी गार्ड में नकली नाम देना। क्या कोई बेहतर तरीका है?

संपादित मैं समझता हूँ कि आप #define और #ifndef निर्देशों (जैसे FOO_A_HPP और BLAH_A_HPP) में एक और वर्णनात्मक नाम का उपयोग करके इस समस्या का समाधान कर सकते हैं, लेकिन मैं जानना चाहता हूँ कि अगर सिफारिश की है या सबसे अच्छा तरीका है । क्या कुछ लोग एक बेहतर फ़ाइल नाम का उपयोग बेहतर समाधान के रूप में करने की सलाह देंगे या क्या इससे कोई फर्क नहीं पड़ता? आप परंपरा का उपयोग करके की सिफारिश करेंगे:

<NAMESPACE>_<CLASS>_HPP 

<CLASS>_HPP 

के बजाय सामान्य रूप में इन समस्याओं से बचने का एक बेहतर मौका देने के लिए?

+0

इसे सी के रूप में क्यों टैग किया गया है? –

+0

मैं हमेशा अपने गार्ड में नामस्थान डालता हूं। स्वचालित उपकरण एक GUID हेडर गार्ड के रूप में रखेंगे। पूरा मुद्दा यह है कि वे ** अद्वितीय होना चाहिए (न सिर्फ आपके प्रोजेक्ट में बल्कि सभी आयामों में सभी फ़ाइलों में अधिमानतः अद्वितीय होने पर अद्वितीय)। –

उत्तर

7

आप इस का समाधान, बस, शीर्ष पर एक ही #define का उपयोग नहीं कर से ...

यह BLAH_A_HPP और FOO_A_HPP आदि का उपयोग करने के लिए इतना है कि #define भी नाम स्थान नाम भी शामिल है बेहतर होगा।

संपादित करें: ठीक है व्यक्तिगत रूप से मैं करने की सलाह देते हैं:

1) हेडर नाम न ही (यानी ... यह हमेशा मदद) और विभिन्न #define नाम का उपयोग करता है भिन्न फ़ाइल नाम का उपयोग करें।
2) कक्षाओं को एक ही चीज़ का नाम न दें। 1 वर्ग प्रति हेडर रखें और कक्षा
3 के बाद शीर्षलेख का नाम दें 3) यदि वे नामस्थान द्वारा अलग-अलग हैं, तो फ़ाइल नाम में नामस्थान और #de 4) आपको एक आईडी जोड़ें # परिभाषित करें कि यह आपके लिए अद्वितीय है (मैं उदाहरण के लिए गोज़ का उपयोग कर सकता हूं)
5) एक बार #pragma का उपयोग करें। यह कंपाइलर्स के लिए उपयोगी है जो इसे है।

हालांकि यह सब स्वाद का मामला है। एक योजना चुनें जो आपके लिए काम करती है और इसके साथ चिपक जाती है। यह गलत और सही नहीं है। जब तक यह काम करता है और सुसंगत है।

+0

समझा, प्रश्न पर अधिक स्पष्टीकरण के लिए मेरा संपादन देखें। क्या आप सामान्य रूप से NAMESPACE_CLASS_HPP के सम्मेलन की अनुशंसा करेंगे? क्या यह फ़ाइल नाम बदलने से बेहतर है या इससे कोई फर्क नहीं पड़ता? – deuberger

+0

@deuberger: फ़ाइल नाम बदलने से कोई फर्क नहीं पड़ता; समस्या डुप्लिकेट के कारण गार्ड नाम शामिल है। और हाँ, मैं गार्ड शामिल करने के लिए NAMESPACE_CLASS_HPP जैसे कुछ का उपयोग करने की अनुशंसा करता हूं। –

+0

यह एक "आंशिक समाधान" सच है ... मैं इसे ठीक कर दूंगा :) – Goz

0

हालांकि C में कोई नामस्थान नहीं है, मुझे लगता है कि यह C और C++ दोनों के लिए काम करता है।

#ifndef BLAH_B_HPP 

और

#ifndef FOO_B_HPP 
1

जब MSVC एक वर्ग यह अपने गार्ड नाम करने के लिए एक GUID जोड़ने मुद्दे की इस तरह से बचने के लिए होगा बनाता है।

+0

यहां कुछ भी नहीं कहता है कि एमएसवीसी का उपयोग कर hes, जो इसके सी ++ के बाद से संभव नहीं है। – alternative

+0

@mathepic: क्या मतलब है कि यह संभव नहीं है क्योंकि यह C++ है, यह बकवास क्या है? यह सुनिश्चित करने के लिए मानक तरीका का एक उदाहरण देना कि हेडर गार्ड पृष्ठभूमि के साथ अद्वितीय है जहां विचार आया था, यह नहीं कह रहा कि एमएसवीसी का उपयोग आवश्यक है। –

+0

@mathepic: नहीं इसमें सबसे निश्चित रूप से सी ++ शामिल है, और यह अभी भी बिंदु के अलावा है। –

0

जैसा कि आपने स्वयं को सुझाव दिया है, ऐसा करने का सामान्य तरीका है कि एक GUID, या एक पूर्ण पथ, या आप क्या जोड़कर अपने गार्ड पहचानकर्ता अद्वितीय बनाते हैं।

कुलपति में वहाँ भी एक pragma आप के लिए शामिल किए जाने के का ख्याल रखना है ++, ताकि आप #if defined(HUMPTYDUMPTY) खुद काटा, यह जाता है की तरह

#pragma once 

के कुछ पुनरावृत्तियों के लिए चारों ओर गया है लिखने की जरूरत नहीं है वीसी ++ अब, लेकिन अन्य कंपाइलरों के लिए आपको जांचना होगा। यह आपको अद्वितीय नामों की तलाश करने में परेशानी भी बचाता है।

संपादित: बस एक नज़र था और इंटरनेट सोचता है कि यह जीसीसी में भी है। लगता है #include शैली गार्ड की तरह बहुत ज्यादा 20 वीं सदी रहे हैं ...

+0

अच्छा बिंदु, हालांकि यह सामान्य रूप से #pragma जैसा लगता है और #pragma एक बार पसंदीदा तरीका नहीं है। देखें: http://stackoverflow.com/questions/787533/is-pragma-once-a-safe-include-guard। – deuberger

+0

बस प्रज्ञा के बारे में पोस्ट पढ़ें। मैं यहां प्रदर्शन के बारे में वास्तव में चिंतित नहीं हूं; सिर्फ यह सोचकर कि आपको जितना अधिक गलती करना है उतना अधिक टाइप करना होगा। यदि आप असंगत कंपाइलर्स के बीच बहुत सारे कोड पोर्टिंग करते हैं तो यह एक समस्या हो सकती है। किसी भी तरह से, कुछ भी नहीं मैं किसी भी नींद खोना होगा। –

2

मुझे आश्चर्य है कि कोई

//src/foo/c.hpp 
#ifndef C_HPP 
#define C_HPP 

#includes "../b.hpp" 
#undef A_HPP 
#includes "a.hpp" 
... 

नीचे के रूप में A_HPP #undef का उपयोग करने का सरल उपाय उल्लेख हो, यह विशेष रूप से अच्छा है, तो foo है/c.hpp एकमात्र फ़ाइल है जिसे बदलने या बदलने की अनुमति है।

+0

अच्छा बिंदु और मैं अब आश्चर्यचकित हूं कि आप इसका जिक्र करते हैं। – deuberger

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