2014-07-08 21 views
9

Sınıfımın korumalı yöntemlerini ve yapıcılarını sınamaya çalışıyorum. Bu amaçla, ben alt sınıf ve C++ 11 using anahtar kelime ile kamuoyuna olarak üyelerini yeniden ihraç etmeye çalıştı: AncakDevralınan yapıcıyı genel yapmak için 'using' anahtar sözcüğünün kullanımı

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(); 
} 

, hem g ++, clang ++ aşağıdaki hatayı üreten, bunu derlemek için başarısız:

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

TestableFoo kurucusu hala run yöntemi herkese açık olsa bile korunur (ayrıca onayladım). Neden böyle? Ya kararları anlayabiliyordum (görünürlük üzerine yazabilme vs.), fakat neden yöntemler ve kurucular arasında bir tutarsızlık var?

+0

Related'i - http://stackoverflow.com/questions/24014240/c11-declaring-factory-a-friend-of-base-class - ama neden cevap vermiyor * neden * – Praetorian

+2

"Neden", muhtemelen, aksi takdirde, bu durumda miras kalmamanın verimsizliğinden daha kötü bir kötülük olarak düşünülebilecek olan yapıcıların * bütününün erişilebilirliğini değiştireceğinden muhtemelen muhtemeldir. Ama bu sadece bir tahmin. –

cevap

4

Standart açıkça kalıtsal kurucular onların erişim düzeylerini korumak belirtiyor:

12,9 miras kurucular [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:

[vakaların listesi atlanmış]

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).

Bunu doğrudan tabiki olarak da arayabilirsiniz:

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

Bu davranış standardı (: 2011 12.9, §4 ISO/IEC 14822): dediklerinde bir uyum olduğunu

X kurucular devralındığı temel sınıfını olan

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

.

istenilen davranışı elde etmek için kullanabilirsiniz:

class TestableFoo : public Foo { 
    public : 
    TestableFoo(int i) : Foo(i) { } 
    using Foo::run; 
}; 
İlgili konular