2011-02-08 18 views
13

कृपया मुझे शिक्षित करें। जबकि इस नहीं हैसी ++ परिपत्र निर्भरता - नामस्थान बनाम संरचना

struct compiles 
{ 
    struct A; 
    struct B 
    { 
     B(const A &a) : member(a.member) { } 
     int member; 
    }; 
    struct A 
    { 
     A(const B &b) : member(b.member) { } 
     int member; 
    }; 
}; 

:: क्यों इस संकलन करता है

namespace doesnt 
{ 
    struct A; 
    struct B 
    { 
     B(const A &a) : member(a.member) { } 
     int member; 
    }; 
    struct A 
    { 
     A(const B &b) : member(b.member) { } 
     int member; 
    }; 
} 

(MSVC 9.0 में)

+1

आपको प्राप्त होने वाली संकलक त्रुटि क्या है? समस्या के समाधान के लिए –

+0

+1 नामस्थान के लिए +1 – TonyK

उत्तर

7

सी ++ में, कक्षा का दायरा विशेष है। किसी भी घोषणा जो वर्ग परिभाषा के अंत में या उसके बाद तक फैली हुई है, स्वचालित रूप से इसकी सदस्य परिभाषाओं (3.3.6 [basic.scope.class]) द्वारा परिभाषित क्षेत्रों में विस्तारित होती है।

इसका मतलब है कि पहले मामले में struct A की पहली घोषणा और struct A की पूर्ण परिभाषा B और उसके कन्स्ट्रक्टर के शरीर में दिखाई दे रही है।

यह गुंजाइश नाम स्थान पर लागू नहीं होता तो में B के निर्माता में दूसरे मामले a.member एक त्रुटि है, क्योंकि struct A की एक परिभाषा अभी तक दिखाई नहीं देता है।

+0

+1 धन्यवाद! – Bill

14

एक class/struct/union परिभाषा के शरीर सभी को एक बार संसाधित किया जाता है, की अनुमति देता है बाद में परिभाषित कक्षाओं के सदस्यों के संदर्भ। namespace को ऊपर से नीचे तक संसाधित किया जाता है, और struct A की अग्रेषित घोषणा आपको परिभाषा के बिना अपने सदस्यों का उपयोग करने की अनुमति नहीं देती है। B के कन्स्ट्रक्टर ऑफ-क्लास की परिभाषा को स्थानांतरित करने का प्रयास करें ताकि आप इसे A की परिभाषा के बाद रख सकें।

+0

+1 :) मानक संदर्भ के लिए –

3

[जी ++ 4.2 के साथ भी परीक्षण किया गया] पहला संकलन करता है क्योंकि संकलक वास्तव में नेस्टेड संरचनाओं को संकलित करने से पहले संरचना के भीतर परिभाषित सभी प्रकारों को चुनता है (बाद में कक्षा के भीतर दिखाई देने वाले निजी विशेषताओं का उपयोग करके सार्वजनिक इनलाइन विधियों के बारे में सोचें) । नेमस्पेस के भीतर कंपाइलर बस ऊपर-नीचे काम करता है और इसमें विशेष नियम नहीं हैं।

0

दोनों संकलित करेंगे यदि आप कन्स्ट्रक्टर के कार्यान्वयन को .cpp फ़ाइल में ले जाते हैं जहां उन्हें वैसे भी होना चाहिए।

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