2014-07-08 10 views
9

मैं अपनी कक्षा के संरक्षित तरीकों और रचनाकारों का परीक्षण करने की कोशिश कर रहा हूं। इस प्रयोजन के लिए, मैं इसे उपवर्ग के लिए, और सी ++ 11 using कीवर्ड के साथ सार्वजनिक रूप अपने सदस्यों को फिर से निर्यात करने की कोशिश की:विरासत कन्स्ट्रक्टर सार्वजनिक बनाने के लिए 'उपयोग' कीवर्ड का उपयोग

class Foo { 
    protected: 
    Foo(int i) {} 
    void run() {} 
}; 

class TestableFoo : public Foo { 
    public: 
    using Foo::Foo; 
    using Foo::run; 
}; 

int main() { 
    TestableFoo foo(7); 
    foo.run(); 
} 

हालांकि, दोनों जी ++ और बजना ++ यह संकलित करने के लिए, निम्न त्रुटि उत्पादन असफल:

test.cpp:13:15: error: ‘TestableFoo::TestableFoo(int)’ is protected 
    using Foo::Foo; 
      ^
test.cpp:18:16: error: within this context 
    TestableFoo foo(7); 
        ^

टेस्टेबलफू कन्स्ट्रक्टर अभी भी संरक्षित है, भले ही run विधि सार्वजनिक हो जाए (मैंने इसे अलग से पुष्टि की)। ऐसा क्यों हैं? मैं या तो निर्णय (विरासत बनाम ओवरराइटिंग दृश्यता) को समझ सकता हूं, लेकिन विधियों और रचनाकारों के बीच एक असंगतता क्यों है?

+0

संबंधित - http://stackoverflow.com/questions/24014240/c11-declaring-factory-a-friend-of-base-class - लेकिन जवाब नहीं देता * क्यों * – Praetorian

+2

"क्यों" शायद इसलिए है क्योंकि अन्यथा यह * सभी * रचनाकारों की पहुंच को बदल देगा, जो इस स्थिति में उन्हें प्राप्त करने में असमर्थ होने की असुविधा से भी बदतर बुरा माना जा सकता है। लेकिन यह सिर्फ एक अनुमान है। –

उत्तर

4

स्टैंडर्ड को स्पष्ट रूप से कहा गया है कि विरासत में मिला कंस्ट्रक्टर्स उसकी पहुंच का स्तर बनाए रखने के लिए:

12,9 विरासत कंस्ट्रक्टर्स [class.inhctor]

1 A using-declaration (7.3.3) that names a constructor implicitly declares a set of inheriting constructors. The candidate set of inherited constructors from the class X named in the using-declaration consists of actual constructors and notional constructors that result from the transformation of defaulted parameters as follows:

[मामलों की सूची छोड़े गए]

4 A constructor so declared has the same access as the corresponding constructor in X. It is deleted if the corresponding constructor in X is deleted (8.4).

आप इसे सीधे पाठ्यक्रम में कॉल कर सकते हैं:

TestableFoo(int i) : Foo(i) { } 
1

यह व्यवहार क्या मानक कहते हैं (2011 12.9, §4 आईएसओ/आईईसी 14,822): के अनुरूप है

A constructor so declared has the same access as the corresponding constructor in X.

जहां X आधार वर्ग है जहाँ से कंस्ट्रक्टर्स विरासत में मिला रहे है।

वांछित व्यवहार पाने के लिए, आप का उपयोग कर सकते हैं:

class TestableFoo : public Foo { 
    public : 
    TestableFoo(int i) : Foo(i) { } 
    using Foo::run; 
}; 
संबंधित मुद्दे