2012-09-06 22 views
5

कक्षा को घोषित क्यों करें जिसे आपने हेडर फ़ाइल के रूप में शामिल किया है?कक्षा को घोषित क्यों करें जिसे आपने हेडर फ़ाइल के रूप में शामिल किया है?

#include "TreeCallObj.h" 
#include "TreeDevObj.h" 
#include "TreeDevCallObj.h" 

class TreeCallObj; //what is the purpose of this line ? 
class TreeDevObj; //what is the purpose of this line ? 
class TreeDevCallObj; //what is the purpose of this line ? 


class Apple 
{ 
public: 
... 
private: 
... 
} 
+1

ऐसा लगता है कि हम कुछ संदर्भ खो रहे हैं। संभवतः कुछ सर्कुलर हेडर फ़ाइल संदर्भ चल रहा है, और 'TreeWhateverObj' कक्षाओं को केवल वर्तमान फ़ाइल में सूचक द्वारा संदर्भित किया जाता है? शायद यह किसी ऐसे व्यक्ति द्वारा लिखा गया था जो वास्तव में उनकी आगे की परिभाषा पसंद करता है। 'ओब्ज' में कक्षा के नामों का प्रत्यय मुझे पागल कोडिंग सम्मेलन की तरह लगता है। – Rook

+0

मैंने पढ़ा है कि अगर परियोजना को बनाने में 10 मिनट लगते हैं तो कक्षा घोषित करने से संकलन समय में सुधार हो सकता है? मुझे नहीं पता कि यह कितना सच है और कितना लाभ है। – jdl

+0

बहुत संभावना नहीं लगता है, लेकिन परीक्षण करने के लिए काफी सरल है। हमें बताएं कि यह कैसे जाता है ;-) – Rook

उत्तर

6

इस पर विचार करें:

//a.h 
#ifndef A_H 
#define A_H 

#include "b.h" 
class A 
{ 
    B* b; 
}; 
#endif 

//b.h 
#ifndef B_H 
#define B_H 

#include "a.h" 
class B 
{ 
    A* a; 
}; 
#endif 

अब आप एक अलग से एक में फ़ाइलों में से एक में शामिल करने का प्रयास करें, आप कहते हैं कि #include "a.h"

संकलक उसे पार्स के रूप में:

#ifndef A_H 
#define A_H 

ठीक - A_H परिभाषित नहीं है सामग्री चिपकाने के लिए

#include "b.h" 

कोशिश:

#ifndef B_H 
#define B_H 

ठीक है, B_H isn के बाद से

परिभाषित नहीं किया गया 0
#include "a.h" 

यह A को परिभाषित नहीं करेगा, क्योंकि A_H परिभाषित किया गया है।तो अगली, हम

class B 
{ 
    A* a; 
}; 

जो, एक त्रुटि को बढ़ावा मिलेगा क्योंकि A परिभाषित या उपयोग करने से पहले घोषित नहीं किया गया था।

आगे की घोषणा इसे ठीक करती है।

बेशक, इसका सबसे अच्छा समाधान बिल्कुल शामिल नहीं है (जब तक आपको बिल्कुल नहीं करना चाहिए)।

+1

संख्यायदि तीसरे मामले में 'ए_एच' पहले से ही परिभाषित किया गया है, तो वर्ग' ए 'पहले से ही उसी दायरे के लिए परिभाषित किया गया होगा। –

+0

@EitanT नहीं, क्योंकि ए में परिभाषित होने से पहले एएच में बीएच शामिल है। सही? –

+0

"यह ए को परिभाषित नहीं करेगा, क्योंकि ए_एच परिभाषित किया गया है। तो अगला, हमारे पास है" - हाँ, और यह शामिल गार्ड के बिंदु है। यदि 'ए_एच' परिभाषित किया गया है, तो ए क्लास पहले ही घोषित कर दी गई है - कोई त्रुटि नहीं। –

3

तो फाइलों में वहाँ वर्गों की परिभाषा है, इसलिए, forward declaration सामान्य मामलों में अनावश्यक है।

5

इस लाइन का उद्देश्य क्या है?

आदर्श रूप से कुछ भी नहीं। यह अनावश्यक है।

हालांकि, जैसा कि @ लूचियन ग्रिगोर ने बताया है, ऐसे बुरे-डिजाइन किए गए कोड हो सकते हैं कि गार्ड और क्रॉस-इन शामिल करने के गलत उपयोग के कारण, आगे की घोषणा आवश्यक हो सकती है।

+0

@LuchianGrigore हाँ। तुम सही थे। –

+0

मुझे यह आवश्यक नहीं है कि बुरी तरह से डिज़ाइन किया गया कोड हो। यह सिर्फ परिपत्र निर्भरता है। –

+0

@EitanT ठीक है, मुझे लगता है कि यह है। यदि कोई क्रॉस-रेफरेंसिंग के बिना किसी समस्या को हल करने में असमर्थ है, तो डिज़ाइन में कोई समस्या है। क्या आप एक उदाहरण प्रदान कर सकते हैं जहां आपको लगता है कि यह पालन करने का एक अच्छा तरीका है? –

1

कोई कारण नहीं। स्थिति के आधार पर आपको एक या दूसरे को करने की ज़रूरत है, लेकिन दोनों नहीं।

0

अपने हेडर फाइल सही मैं घोषित क्योंकि वे पहले से हैडर

1

यह खड़ा के रूप में में घोषित करना चाहिए का कोई मतलब नहीं देख रहे हैं, तो कोई ज़रूरत नहीं है।

हालांकि, इस ऐतिहासिक दृष्टि से विकसित किया है हो सकता है: कुछ बिंदु पर, एक अधूरी प्रकार पर्याप्त हो सकता है:

class Foo; 

struct Gizmo 
{ 
    void f(Foo); 
}; 

फिर, बाद में किसी समय, लेखक का फैसला किया वह पूरा प्रकार की जरूरत:

#include "Foo.hpp" 

class Foo; 

struct Gizmo 
{ 
    void f(Foo); 
    Foo x; 
}; 

मूल कोड अभी-आवश्यक शीर्ष लेख शामिल किए जाने के साथ संशोधन किया गया हो सकता है ...

+0

या, 'संरचना Gizmo {Foo * foo; } 'जिसे बाद में' संरचना Gizmo {Foo foo 'में बदल दिया गया है; } '। तो पूर्व के लिए, एक घोषणा 'कक्षा फू;' पर्याप्त है, लेकिन बाद के लिए परिभाषा की आवश्यकता है इसलिए '# शामिल "foo.hpp" '। :-) – Nawaz

+0

@ नवाज़: हाँ! लेकिन मैं किसी को यह सुझाव नहीं देना चाहता था कि 'फू *' स्वीकार्य है C++ :-) मैं क्षणिक रूप से 'unique_ptr ' के साथ टकरा रहा था ... –

+0

जब आप * ऐतिहासिक रूप से * के बारे में बात करते हैं, तो आप 'फू * के बारे में बात कर सकते हैं * '* आराम से * ;-)। कोई भी आपको कम नहीं करेगा: पी (ठीक है, कम से कम मुझे नहीं)। – Nawaz

1

मैं वहाँ इस के लिए कुछ इतिहास है लगता है कि होगा। मूल रूप से कोडर ने हेडर फ़ाइलों को शामिल करने की कोशिश नहीं की और इसके बजाय आगे की घोषणाओं का उपयोग किया। फिर जैसे ही कोड का विस्तार हुआ, उन्होंने पाया कि उन्हें हेडर फाइलों की आवश्यकता है, लेकिन आगे की घोषणाओं को हटाने के लिए परेशान नहीं था।

जैसा कि अन्य ने कहा है कि वर्ग घोषणा के बाद आगे की घोषणा करने का कोई उद्देश्य नहीं है।

1

मुझे पता है कि आपके शीर्षलेख में एकाधिक समावेशन के खिलाफ गार्ड नहीं हैं। यह भी संभव है कि कुछ अन्य हेडर (शीर्षलेखों में आमतौर पर ऐसे गार्ड होते हैं) में हेडर बैक शामिल होता है। नतीजतन यह संकलित नहीं किया था। तो किसी ने गलत बग को ठीक करने के लिए आगे की घोषणाओं को जोड़ा।

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

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