2016-09-21 4 views
5
class Base 
{ 
protected: 
    void func1(); 
}; 

class Derived : public Base 
{ 
friend class Third; 
}; 

class Third 
{ 
    void foo() 
    { 
     Derive d; 
     d.func1(); 
    } 
}; 

मैं VC14 में कोड (विजुअल स्टूडियो 2015) withour त्रुटि संकलन लेकिन VC12 से त्रुटि प्राप्त कर सकते हैं (विजुअल स्टूडियो 2013)अलग व्यवहार के बारे में C++ VC12 से मैत्री और विरासत और VC14

cannot access protected member declared in class 'Base' 

जो सही है? विरासत के साथ इस तरह की स्वतंत्रता की शुद्धता क्या है?

एमएसडीएन https://msdn.microsoft.com/en-us/library/465sdshe.aspx या http://en.cppreference.com/w/cpp/language/friend से ऐसा लगता है कि दोस्ती संक्रमणीय नहीं है और विरासत में नहीं मिल सकती है। हालांकि मुझे लगता है कि यह वास्तव में इस कोड उदाहरण का मामला नहीं है।

लेकिन क्यों वीसी 14 मुझे कोई त्रुटि नहीं मिलेगा?

यदि वीसी 14 सही है, तो मैं कोड को "संशोधित" कैसे कर सकता हूं ताकि वीसी 12 भी ठीक हो? संरक्षित func1() को फिर से कक्षा में व्युत्पन्न करने के लिए परिभाषित किया गया है?

+0

मुझे शक है कि आप किसी भी संकलक पर कि कोड को संकलित कर सकते हैं: यह कुछ अर्द्ध कोलन कमी है। – rubenvb

+0

जीसीसी http://ideone.com/Zue7WL पर त्रुटि नहीं है। –

+0

अच्छा सवाल। पारगमन और विरासत लागू नहीं होती है क्योंकि यह व्युत्पन्न वर्ग है जो तीसरे को मित्र के रूप में घोषित करता है। कोड दोनों clang और gcc द्वारा स्वीकार किया जाता है। – drRobertz

उत्तर

4

लेखन त्रुटि ठीक करने के बाद, टिप्पणी इनलाइन:

class Base 
{ 
protected: 
    void func1(); // protected access 
}; 

class Derived : public Base 
{ 
    // implicit protected func1, derived from Base 

    // this means 'make all my protected and private names available to Third' 
    friend class Third; 
}; 

class Third 
{ 
    void foo() 
    { 
     Derived d; 
     // func1 is a protected name of Derived, but we are Derived's friend 
     // we can therefore access every member of Derived 
     d.func1(); 
    } 
}; 

VC14 सही है। VC12 के लिए

संभावित वैकल्पिक हल:

class Base 
{ 
protected: 
    void func1(); 
}; 

class Derived : public Base 
{ 
    protected: 
    using Base::func1; 

    private: 
    friend class Third; 
}; 


class Third 
{ 
    void foo() 
    { 
     Derived d; 
     d.func1(); 
    } 
}; 

एक अन्य संभावित समाधान, (कुंजी-आधारित पहुँच का उपयोग करते हुए)

class Third; 
class Func1Key 
{ 
    private: 
    Func1Key() = default; 
    friend Third; 
}; 

class Base 
{ 
protected: 
    void func1(); 
}; 

class Derived : public Base 
{ 
public: 
    void func1(Func1Key) 
    { 
    Base::func1(); 
    } 
}; 


class Third 
{ 
    void foo() 
    { 
     Derived d; 
     d.func1(Func1Key()); 
    } 
}; 
+0

@ सोंग्युन्याओ का मतलब है कि यह निजी बीमा है क्योंकि –

+0

@juanchopanza में एक और वर्ग दिख रहा है। –

+0

@songyuanyao सही। धन्यवाद। –

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