2009-06-20 21 views
120

संभव डुप्लिकेट:
Forward declaration of nested types/classes in C++मैं एक आंतरिक कक्षा घोषित कैसे करूं?

मैं बहुत की तरह एक वर्ग कहीं और है ...

class Container { 
public: 
    class Iterator { 
     ... 
    }; 

    ... 
}; 

, मैं संदर्भ द्वारा एक कंटेनर :: इटरेटर पास करना चाहते हैं, लेकिन मैं हेडर फ़ाइल शामिल नहीं करना चाहता हूं। अगर मैं कक्षा घोषित करने की कोशिश करता हूं, तो मुझे संकलन त्रुटियां मिलती हैं।

class Container::Iterator; 

class Foo { 
    void Read(Container::Iterator& it); 
}; 

संकलन ऊपर कोड देता है ...

test.h:3: error: ‘Iterator’ in class ‘Container’ does not name a type 
test.h:5: error: variable or field ‘Foo’ declared void 
test.h:5: error: incomplete type ‘Container’ used in nested name specifier 
test.h:5: error: ‘it’ was not declared in this scope 

कैसे मैं आगे इस वर्ग घोषणा कर सकते हैं तो मैं हेडर फाइल कि इटरेटर वर्ग वाणी शामिल करने के लिए नहीं है?

उत्तर

102

यह संभव नहीं है। आप कंटेनर के बाहर एक घोंसला वाली संरचना घोषित नहीं कर सकते हैं। आप केवल इसे कंटेनर के भीतर घोषित कर सकते हैं।

आप निम्न

  • में से एक करने की आवश्यकता होगी ताकि नेस्टेड वर्ग पूरी तरह से पहले
  • एक आम आधार वर्ग बनाएं परिभाषित किया गया है वर्ग गैर नेस्टेड
  • अपने घोषणा क्रम बदलें बनाओ जिसे दोनों कार्यों में इस्तेमाल किया जा सकता है और नेस्टेड क्लास द्वारा कार्यान्वित किया जा सकता है।
+2

आम आधार वर्ग सबसे अधिक मेरे अंत में उपयोग किया जाने वाला समाधान है। – Coyote

+0

यदि आप चाहें तो आप इसके आसपास काम करने के लिए मित्र का उपयोग कर सकते हैं। –

+1

यह गलत है: http: //en.cppreference।com/डब्ल्यू/सीपीपी/भाषा/nested_types – Nikerboker

18

मैं आगे विश्वास नहीं करते एक अधूरी वर्ग कार्यों पर की अंदरूनी वर्ग की घोषणा (क्योंकि वर्ग परिभाषा के बिना अगर वहाँ वास्तव में एक आंतरिक वर्ग है, वहाँ जानने का कोई तरीका नहीं है)।

class Container { 
public: 
    class Iterator; 
}; 

तो एक अलग शीर्षक में, लागू कंटेनर :: इटरेटर:

class Container::Iterator { 
}; 

फिर # शामिल केवल तो तुम एक आगे घोषित भीतरी वर्ग के साथ, कंटेनर की परिभाषा में शामिल करना होगा कंटेनर हैडर (या के बारे में आगे चिंता मत घोषित करने और बस दोनों शामिल हैं)

+4

पहले अनुच्छेद संश्लेषण में भाग को छोड़कर अच्छा जवाब। "वास्तव में एक आंतरिक वर्ग है या नहीं, यह जानने का कोई तरीका नहीं है" इस संदर्भ में समझ में नहीं आता है और यह सटीक होने के लिए संदिग्ध है। आगे की घोषणा का पूरा बिंदु यह है कि आप संकलक को बता रहे हैं कि एक वर्ग (या इस मामले में, एक आंतरिक वर्ग) है। आपका विशिष्ट विवरण सामान्य वर्गों के समान ही होगा और इसका मतलब यह होगा कि आप कुछ भी घोषित नहीं कर सकते हैं। – Aaron

1

मैं कोई रास्ता नहीं बिल्कुल ऐसा करने के लिए आप क्या चाहते हैं के बारे में पता है, लेकिन यहां एक समाधान, अगर आप टेम्पलेट का उपयोग करने के लिए तैयार हैं:

// Foo.h 
struct Foo 
{ 
    export template<class T> void Read(T it); 
}; 

// Foo.cpp 
#include "Foo.h" 
#include "Container.h" 
/* 
struct Container 
{ 
    struct Inner { }; 
}; 
*/ 
export template<> 
    void Foo::Read<Container::Inner>(Container::Inner& it) 
{ 

} 

#include "Foo.h" 
int main() 
{ 
    Foo f; 
    Container::Inner i; 
    f.Read(i); // ok 
    f.Read(3); // error 
} 

उम्मीद है, यह मुहावरा आप के लिए कुछ काम का हो सकता (और उम्मीद है कि अपने संकलक ईडीजी आधारित है और निर्यात को लागू करता है;))।

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