2016-05-06 8 views
7

मुझे यह अजीब समस्या मिल रही है जो मुझे नहीं पता कि ऐसा क्यों होता है। पहली और निम्नलिखित कोड के टुकड़े के दूसरे संकलन, जबकि तीसरे नहीं करता है:पैरामीटर के रूप में निजी नेस्टेड प्रकार का उपयोग

संकलित:

class Foo { 
public: 
    Foo() { Bar(); } 

private: 
    class Bar {}; 
}; 

संकलित:

class Foo { 
    class Bar {}; // Or only forward declare here and define later 

public: 
    Foo(Bar) {} 
} 

संकलन नहीं करता:

class Foo { 
public: 
    Foo(Bar) {} 

private: 
    class Bar {}; 
}; 

पहली बार संकलन करने में तीसरा असफल हो जाता है?

+0

वाह। विकल्प तीन वीएस2015 के कंपाइलर मृत मारता है। अक्सर संकलक दुर्घटना को न देखें। – user4581301

+0

वैसे भी, 'Foo'3 के रचनाकारों को' Foo :: Bar' प्रदान करना होगा, और वे तब से निजी नहीं हो सकते हैं। यह इस कोड को एक असंगत स्थिति में रखता है। आश्चर्य नहीं है कि यह संकलित नहीं करता है, लेकिन नियमों का उल्लेख नहीं कर सकता है। लेकिन फिर दूसरा संकलन क्यों करता है? 'बार 'भी निजी होगा, लेकिन' फू 'कन्स्ट्रक्टर से पहले परिभाषित किया जाएगा। – user4581301

उत्तर

4

आम तौर पर, सी ++ में, आप केवल उन घोषणाओं का संदर्भ दे सकते हैं जो पहले अनुवाद इकाई में किए गए थे। हालांकि, कक्षा परिभाषा के भीतर, सदस्य कार्यों की परिभाषा को बाद में कक्षा में किए गए घोषणाओं को संदर्भित करने की अनुमति है। असल में, कंपाइलर आपकी कक्षा की परिभाषाओं को पुनर्गठन करता है ताकि वे काम कर सकें जैसे कि वे कक्षा के ठीक बाद लिखे गए थे।

लेकिन यह केवल कार्य परिभाषाओं के बारे में सच है। फ़ंक्शन के घोषणा फ़ंक्शन (पैरामीटर प्रकार सहित) को ऐसा करने की अनुमति नहीं है। वे केवल उन घोषणाओं का संदर्भ दे सकते हैं जो फ़ाइल आदेश में पहले से ही किए जा चुके हैं।

तो तुम यह कर सकते हैं:

class Test 
{ 
    public: 
     void Func(int x) {Inner foo;} 

    private: 
     class Inner {}; 
}; 

लेकिन यह नहीं:

class Test 
{ 
    public: 
     void Func(Inner x) {} 

    private: 
     class Inner {}; 
}; 
+2

दूसरे शब्दों में, निकायों की पूर्ण दृश्यता है, लेकिन विधि परिभाषा नहीं है। और यह मुझे मूर्ख की तरह महसूस करता है क्योंकि [मैंने आज सुबह यह पढ़ा।] (Http://stackoverflow.com/questions/37079271/declaring-class-variables-after-assigning-them-values-in-c) – user4581301

2

पहला उदाहरण बाहर के लिए private Bar के बारे में कुछ भी खुलासा नहीं करता है, जबकि तीसरा करता है।

तीसरा उदाहरण काफी कह रहा है कि कुछ वर्ग Foo मौजूद है, जिसमें Bar प्रकार के एकल तर्क के साथ निर्माता है। लेकिन Bar बाहर के लिए अज्ञात है। इस तरह के कन्स्ट्रक्टर को कॉल करने की कल्पना करो।

Foo f{Foo::Bar{}}; 

कुछ में शायद परिणाम होगा Foo::Bar तरह दुर्गम है।

+1

यह मेरी सोच भी है, लेकिन यह समझ में नहीं आता है कि कैसे 'Foo' संस्करण 2 को कंपाइलर से पास मिलता है। – user4581301

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