2011-12-15 12 views
25

मेरे पास दो शीर्ष वर्ग दोनों अलग-अलग शीर्षलेख फ़ाइलों में परिभाषित हैं। प्रत्येक फ़ाइल में एक फ़ील्ड होता है जो अन्य वर्ग का प्रकार होता है। अब मैं प्रत्येक फ़ाइल के शीर्षलेख में अन्य फ़ाइल के शीर्षलेख में शामिल हूं, लेकिन कंपाइलर त्रुटियां उत्पन्न कर रहा है। मैं क्या खो रहा हूँ?सी ++ हेडर फाइलें एक दूसरे के साथ पारस्परिक रूप से

+0

किस प्रकार का "फ़ील्ड"? – fge

उत्तर

33

आप प्रत्येक वर्ग में "एक ऐसा क्षेत्र नहीं है जो अन्य वर्ग का प्रकार है"; यह एक पुनरावर्ती परिभाषा होगी और न केवल संकलक इसे समझने में सक्षम नहीं होगा, यह तार्किक अर्थ भी नहीं बनाता है।

प्रत्येक वर्ग में एक वर्ग है जो कि अन्य वर्ग का प्रकार है, वह असंभवता है जिसे आप केवल एम.सी. में देखते हैं। Escher चित्र, या एनिमेशन उसके इस तरह:

 

                                            based on Escher's "Print Gallery" Lithograph, 1956

                                            स्रोत: escherdroste.math.leidenuniv.nl

                        Escher के "प्रिंट गैलेरी" लिथोग्राफ, 1956 के आधार पर, see Wikipedia

 

दो क्षेत्रों में से एक तो के रूप में पुनरावर्ती रोकथाम को तोड़ने के लिए, एक सूचक होना होगा, और तार्किक असंभवता से बचें।

जो हमें अगली समस्या में लाता है: यदि कक्षा बी में कक्षा ए का एक उदाहरण होना है, तो जाहिर है, ए को कक्षा बी से पहले घोषित किया जाना चाहिए, ताकि बी को संकलित करते समय ए को पहले से ही संकलक के लिए जाना जाता है लेकिन यदि कक्षा ए से पहले कक्षा ए घोषित किया गया है, तो हम ए में बी को सूचक कैसे घोषित कर सकते हैं? कक्षा बी अभी तक ज्ञात नहीं है जब ए संकलित है! इसका उत्तर एक विशेष निर्माण है जिसे अग्रेषित घोषणा कहा जाता है जो इस तरह की स्थितियों को समायोजित करने के लिए ठीक से मौजूद है।

class B; 
सभी यह संकलक है कि वहाँ एक वर्ग बी यह वर्ग बी की सामग्री के बारे संकलक कुछ नहीं बताता है कहा जाता हो जाएगा कह रहा है

, इसलिए वहाँ है: वर्ग बी के एक आगे घोषणा इस तरह दिखता है बहुत कम हम इसके साथ क्या कर सकते हैं, लेकिन हम एक बात कर सकते हैं: बी को घोषित संकेत

तो, समस्या का पूर्ण समाधान इस तरह दिखता है:

फ़ाइल "आह":

/* This is called a "forward declaration". We use it to tell the compiler that the 
    identifier "B" will from now on stand for a class, and this class will be defined 
    later. We will not be able to make any use of "B" before it has been defined, but 
    we will at least be able to declare pointers to it. */ 
class B; 

class A 
{ 
    /* We cannot have a field of type "B" here, because it has not been defined yet. 
     However, with the forward declaration we have told the compiler that "B" is a 
     class, so we can at least have a field which is a pointer to "B". */ 
    B* pb; 
} 

फ़ाइल "B.h":

#include "A.h" 

class B 
{ 
    /* the compiler now knows the size of "A", so we can have a field of type "A". */ 
    A a; 
} 
+1

[एनीमेशन स्रोत] (http://escherdroste.math.leidenuniv.nl/index.php?menu=animation) – Potatoswatter

+0

@Potatoswatter बहुत बहुत धन्यवाद! मैंने छवि के कैप्शन में संशोधन किया। –

17

आपको अन्य लोगों के अंदर हेडर फ़ाइलों को शामिल नहीं करना चाहिए, बस अपनी स्रोत फ़ाइलों में हेडर फाइलें शामिल करें। ,

// Class1.h 
#ifndef __CLASS_1_H 
#define __CLASS_1_H 

// content 

#endif 
+6

नोट: आगे की घोषणाओं का अर्थ है कि आप केवल उस वर्ग का उपयोग हेडर फ़ाइल में पॉइंटर के रूप में कर सकते हैं। एक वर्ग उदाहरण नहीं है। –

+0

अच्छा बिंदु, मैं इसका उल्लेख करना भूल गया! –

+1

आप इसे फ़ंक्शन की घोषणा में और संदर्भ प्रकार के भाग के रूप में रिटर्न प्रकार या पैरामीटर प्रकार के रूप में भी उपयोग कर सकते हैं। –

2

आप शायद घोषणा आगे उपयोग करना चाहते हैं:

// In Class1.h 
class Class2; 

// In class2.h 
class Class1; 

इसके अलावा, आप एक फाइल दो बार पूर्वप्रक्रमक का उपयोग कर शामिल किया जा रहा के खिलाफ की रक्षा कर सकते हैं:

हेडर में आप एक आगे घोषणा का उपयोग कर सकते जब तक आप वास्तव में एक दूसरे में प्रत्येक वर्ग का उदाहरण नहीं रखना चाहते हैं। इस मामले में आपको कुछ भी उपयोग नहीं करना चाहिए।

12

मैं जानता हूँ कि यह एक पुराने विषय है, लेकिन हो सकता है आप अभी भी समाधान में रुचि रखते हैं!

वास्तव में सी ++ में आप पॉइंटर्स का उपयोग किए बिना दो कक्षाओं का उपयोग कर सकते हैं और यहां यह कैसे करना है।

फ़ाइल: a.h

#include <b.h> 

class A { 
    B<> b; 
} 

फ़ाइल:

class A; 

template<typename T = A> 
class B { 
    T a; 
} 

b.h फ़ाइल: main.cpp

#include "a.h"  
A a; 

और बस!

बेशक यह जिज्ञासा के लिए है :)

+2

मैं आपको इसके लिए +1 दूंगा :-) – MegaManX

+0

धन्यवाद, यह आपकी तरह है :) – Boynux

+0

क्या आपने इसे संकलित करने का प्रयास किया है? एमएसवीसी मुझे त्रुटि देता है: '" बी :: ए "एक अपरिभाषित वर्ग का उपयोग करता है" ए "' – kinokijuf

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