2011-04-04 12 views
11

मुझे परिपत्र निर्भरताओं के बारे में पता है, लेकिन आगे की घोषणाओं के साथ भी मुझे यह क्षेत्र मिलता है। मैं क्या गलत कर रहा हूँ?अपूर्ण प्रकार की संरचना का अमान्य उपयोग, आगे की घोषणा के साथ भी

// facility.h 
class Area; 

class Facility { 
public: 
    Facility(); 
    Area* getAreaThisIn(); 
    void setAreaThisIsIn(Area* area); 
private: 
    Area* __area; 
}; 

// facility.cpp 
#include "facility.h" 
#include "area.h" 
{ ... } 

// area.h 
class Facility; 
class Area { 
public: 
    Area(int ID); 
    int getId(); 

private: 
    std::list<Facility*> _facilities; 
}; 

// area.cpp 
#include "area.h" 
#include "facility.h" 

तो यह ठीक संकलित है, लेकिन आप एक पूर्ण घोषणा ही नहीं, आगे घोषणा की जरूरत है अगर मैं

// foo.h 
#include "facility.h" 
class Foo { .. }; 

// foo.cpp 
#include "foo.h" 
void Foo::function() { 
    Facility* f = new Facility(); 
    int id = f->getAreaThisIsIn()->getId(); 

कर जब मैं invalid use of incomplete type struct Area

+3

क्या आपने ** क्षेत्र.h ** को शामिल किया है जो आप 'Foo :: function() 'को परिभाषित कर रहे हैं? –

+0

मैंने 'सुविधा' में 'getAreaThisIn()' टाइपो को सही करने के बाद g ++ ('सुविधा' और' क्षेत्र' विधियों की स्टब परिभाषाओं में) जोड़कर इसे संकलित करने का प्रयास किया है ('getAreaThisIsIn() 'होना चाहिए) यह मेरे लिए संकलित है। हालांकि मेरे 'Foo.cpp' में दोनों शीर्षलेख शामिल थे। – QuantumMechanic

+3

ध्यान दें कि पहचानकर्ता जो दो अंडरस्कोर से शुरू होते हैं ('__area' मैं आपको देख रहा हूं) कार्यान्वयन द्वारा आरक्षित हैं और इनका उपयोग नहीं किया जाना चाहिए। –

उत्तर

8

Facility* f = new Facility(); के लिए मिलता है।

+0

आपका क्या मतलब है? मैंने सोचा कि सीपीपी में काफी अच्छा है? – robev

+1

@robev 'सुविधा.h' सहित, ठीक काम करना चाहिए, जब तक कि अन्य त्रुटियां न हों। –

+1

@robev - यदि आप 'Foo' क्लास हेडर और इसकी स्रोत फ़ाइल दिखाते हैं तो चीजें साफ़ हो जाएंगी। – Mahesh

4

क्या आपने foo.cpp में दोनों क्षेत्र.h और सुविधा.h शामिल किए हैं (माना जाता है कि यह वह फ़ाइल है जहां आपको त्रुटि मिलती है)?

+0

नहीं, मुझे दोनों को शामिल करना होगा? – robev

+3

हां, चूंकि आप अपने कोड में क्षेत्र और सुविधा दोनों उदाहरणों के लिए सदस्य फ़ंक्शंस को कॉल कर रहे हैं, आपको करना होगा। –

19

स्पष्ट करने के लिए: एक आगे घोषणा आप अगर बहुत ही सीमित तरीके एक वस्तु पर संचालित करने के लिए अनुमति देता है:

struct Foo; // forward declaration 

int bar(Foo* f); // allowed, makes sense in a header file 

Foo* baz(); // allowed 

Foo* f = new Foo(); // not allowed, as the compiler doesn't 
        // know how big a Foo object is 
        // and therefore can't allocate that much 
        // memory and return a pointer to it 

f->quux(); // also not allowed, as the compiler doesn't know 
      // what members Foo has 

आगे घोषणाओं कुछ मामलों में कर सकते हैं। उदाहरण के लिए, यदि शीर्षलेख में फ़ंक्शंस केवल ऑब्जेक्ट्स के बजाय ऑब्जेक्ट्स पर पॉइंटर्स लेते हैं, तो आपको उस हेडर के लिए पूरी श्रेणी परिभाषा #include की आवश्यकता नहीं है। यह आपके संकलन के समय में सुधार कर सकते हैं। लेकिन उस शीर्षलेख के लिए कार्यान्वयन को #include की प्रासंगिक परिभाषा की आवश्यकता है, क्योंकि आप संभावित रूप से उन वस्तुओं को आवंटित करना चाहते हैं, उन वस्तुओं पर कॉल विधियों आदि को आवंटित करना चाहते हैं और आपको ऐसा करने के लिए आगे की घोषणा से अधिक की आवश्यकता है।

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