इस बारे में सोचने का तरीका "एक कंपाइलर की तरह सोचना" है।
कल्पना कीजिए कि आप एक कंपाइलर लिख रहे हैं। और आप इस तरह से कोड देखें।
// file: A.h
class A {
B _b;
};
// file: B.h
class B {
A _a;
};
// file main.cc
#include "A.h"
#include "B.h"
int main(...) {
A a;
}
जब आप .cc फ़ाइल संकलित कर रहे हैं (याद रखें कि .cc और .h .h संकलन की इकाई नहीं है), तो आपको ऑब्जेक्ट के लिए स्थान आवंटित करने की आवश्यकता है A
। तो, ठीक है, फिर कितनी जगह? स्टोर करने के लिए पर्याप्त B
! B
तब का आकार क्या है ? स्टोर करने के लिए पर्याप्त A
! उफ़।
स्पष्ट रूप से एक परिपत्र संदर्भ जिसे आपको तोड़ना होगा।
आप इसे संकलक के बजाय आरक्षित स्थान की अनुमति देकर इसे तोड़ सकते हैं, क्योंकि यह अग्रिम-बिंदुओं और संदर्भों के बारे में जानता है, उदाहरण के लिए, हमेशा 32 या 64 बिट्स (वास्तुकला के आधार पर) होंगे और इसलिए यदि आप (या तो एक) द्वारा प्रतिस्थापित किया गया है एक सूचक या संदर्भ, चीजें बहुत अच्छी होंगी। मान लीजिए कि हम इसमें प्रतिस्थापित करते हैं A
:
// file: A.h
class A {
// both these are fine, so are various const versions of the same.
B& _b_ref;
B* _b_ptr;
};
अब हालात बेहतर हैं। कुछ हद तक। main()
अभी भी कहता है:
// file: main.cc
#include "A.h" // <-- Houston, we have a problem
#include
, सभी विस्तार और उद्देश्यों के लिए (यदि आप प्रीप्रोसेसर को बाहर निकालते हैं) बस फ़ाइल को .cc में कॉपी करता है । तो वास्तव में, .cc ऐसा दिखता है:
// file: partially_pre_processed_main.cc
class A {
B& _b_ref;
B* _b_ptr;
};
#include "B.h"
int main (...) {
A a;
}
आप देख सकते हैं कि संकलक इससे क्यों नहीं निपट सकता है - इसका कोई पता नहीं है कि B
यह क्या है - यह पहले कभी प्रतीक भी नहीं देखा है।
तो चलिए कंपाइलर के बारे में बताते हैं B
। इसे आगे की घोषणा के रूप में जाना जाता है , और इस उत्तर में आगे चर्चा की जाती है ।
// main.cc
class B;
#include "A.h"
#include "B.h"
int main (...) {
A a;
}
यह काम करता है । यह महान नहीं है । लेकिन इस बिंदु पर आपको परिपत्र संदर्भ समस्या की समझ होनी चाहिए और हमने इसे "ठीक" करने के लिए क्या किया है, भले ही यह फिक्स खराब हो।
यह फिक्स खराब होने का कारण यह है कि अगले व्यक्ति को इसका उपयोग #include "A.h"
करने B
से पहले घोषित करना होगा और एक भयानक #include
त्रुटि प्राप्त होगी । तो आइए घोषणा को आह में ही आगे बढ़ाते हैं।
// file: A.h
class B;
class A {
B* _b; // or any of the other variants.
};
और भा में , इस बिंदु पर, आप बस #include "A.h"
सीधे कर सकते हैं।
// file: B.h
#include "A.h"
class B {
// note that this is cool because the compiler knows by this time
// how much space A will need.
A _a;
}
HTH।