2012-06-07 16 views
6

मैं bellow इस कोड के बारे में दो सवाल है:दोस्त कार्यों

namespace A { class window; } 

void f(A::window); 

namespace A 
{ 
    class window 
    { 
    private: 
     int a; 
     friend void ::f(window); 
    }; 
} 

void f(A::window rhs) 
{ 
    std::cout << rhs.a << std::endl; 
} 

1) कारण है कि मैं ऐसा करने से वैश्विक होने के लिए विंडो वर्ग के अंदर च सदस्य समारोह अर्हता प्राप्त करने की आवश्यकता है :: एफ (खिड़की)?

2) मुझे इस विशेष मामले में फ़ंक्शन f (ए :: विंडो) की पूर्ववत करने की आवश्यकता क्यों है, जबकि जब कक्षा को नामस्थान के अंदर परिभाषित नहीं किया जाता है तो फ़ंक्शन घोषित होने के बाद फ़ंक्शन घोषित किया जाना ठीक है दोस्त।

+0

यहां एक त्वरित स्पष्टीकरण है कि कौन से दोस्ताना वर्ग http://www.cplusplus.com/doc/tutorial/inheritance/ –

+0

@ हंस क्षमा करें, लेकिन यह मेरे प्रश्न – AlexDan

+1

@ हंस से है, कृपया, कृपया लिंक न करें cplusplus.com - http://programmers.stackexchange.com/q/88241/36523 – Griwes

उत्तर

4

जब आप एक दोस्त के रूप में f() घोषित करते हैं तो यह वास्तव में पहले से मौजूद नहीं होने पर मौजूदा श्रेणी (A) के संलग्न नामस्थान में किया जाता है।

तो यह है ...

namespace A 
{ 
    class window 
    { 
    private: 
     friend void ::f(window); 
    }; 
} 

अनिवार्य रूप से यह हो जाता है ...

namespace A 
{ 
    class window; 
    void f(window); 

    class window 
    { 
    private: 
     friend void f(window); 
    }; 
} 

संपादित करें: यहाँ सी ++ मानक से एक टुकड़ा है कि explicltly इस परिदृश्य के बारे में वार्ता:

मानक 7.3.1.2/3:

नामस्थान में घोषित हर नाम उस नामस्थान का सदस्य है। यदि किसी नॉनोकोकल क्लास में कोई मित्र घोषित करता है तो पहले क्लास या फ़ंक्शन की घोषणा करता है, तो क्लास क्लास या फ़ंक्शन सबसे व्यस्त नामस्थान का सदस्य होता है। दोस्त का नाम अयोग्य लुकअप (3.4.1) या योग्य लुकअप (3.4.3) द्वारा नहीं मिलता है जब तक कि नामस्थान स्कोप में मिलान की घोषणा नहीं की जाती (या तो कक्षा परिभाषा को दोस्ती देने से पहले या बाद में)।

+0

तो, ऊपर दिए गए उदाहरण के अनुसार, f (विंडो) को नेमस्पेस ए का सदस्य माना जाता है? –

+0

@ विष्णुपेडर्डी हां। –

+0

क्या होगा अगर एफ (विंडो) को अपने नाम के नामस्थान में नामस्थान बी परिभाषित किया गया है? क्या एफ (विंडो) नामस्थान ए और नेमस्पेस बी से संबंधित होगा? –

3

1 के लिए), आपका फ़ंक्शन नेमस्पेस में नहीं है, इसलिए आपको कंपाइलर को नामस्थान के बाहर खोजने के लिए कहने के लिए :: का उपयोग करना होगा।

अन्यथा, यह केवल नामस्थान के अंदर फ़ंक्शन की तलाश करेगा (यही कारण है कि वे मौजूद हैं)। कोएनिग लुकअप यहां लागू नहीं होता है, क्योंकि विंडो क्लास नामस्थान के अंदर है।

2 के बारे में भी निश्चित नहीं है) हालांकि, लेकिन मुझे लगता है कि यह 1 से संबंधित है)।

1

1) क्योंकि फ़ंक्शन f को वर्तमान नामस्थान के बाहर घोषित और परिभाषित किया गया है। यदि आपने अपनी कक्षा की परिभाषा को समान नामस्थान में फ़ंक्शन के रूप में स्थानांतरित किया है या नहीं, तो वैश्विक या अन्यथा आपको इसकी आवश्यकता नहीं होगी।

2) आपको संदर्भित होने से पहले हमेशा एक फ़ंक्शन घोषित करने की आवश्यकता होती है। आपकी कक्षा फ़ंक्शन को मित्र कथन के साथ संदर्भित करती है।

+0

रेफ्रेनिस से आपका क्या मतलब है? इस बारे में क्या है कि कक्षा किसी भी नामास्पेस के अंदर नहीं है, यहां एक ही मामला नहीं है? – AlexDan

+0

यह कार्य देखने में सक्षम होना चाहिए। यदि वर्ग समान नामस्थान में फ़ंक्शन परिभाषा के रूप में है, तो यह इसे ढूंढने में सक्षम हो सकता है लेकिन घोषणा मामलों का आदेश। यही कारण है कि आपके समारोह की परिभाषा कक्षा घोषणा के बाद आनी चाहिए क्योंकि यह उस वर्ग के सदस्य का उपयोग करता है। – AJG85

+0

(2) के बारे में, CaptainObvlious के जवाब देखें - वहाँ एक subtly है। एलेक्सदान यहां बिल्कुल सही नहीं है। कभी-कभी, किसी मित्र घोषणा को पहले घोषित फ़ंक्शन को संदर्भित करने की आवश्यकता नहीं होती है - इसके बजाय, मित्र घोषणा स्वयं फ़ंक्शन की आधिकारिक घोषणा के रूप में गिना जाता है, और फ़ंक्शन को बाद में परिभाषित किया जा सकता है। CaptainObvlious के जवाब देखें। –

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