问题
I am trying to test protected methods and constructors of my class. For this purpose, I tried to subclass it, and re-export its members as public with C++11 using keyword:
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();
}
However, both g++ and clang++ fail to compile it, producing the following error:
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 constructor is still protected, even though run method becomes public (I confirmed it separately). Why is that so? I could understand either decision (inheriting vs. overwriting visibility), but why is there an inconsistency between methods and constructors?
回答1:
The Standard explicitly states that inherited constructors retain their access levels:
12.9 Inheriting constructors [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
Xnamed in the using-declaration consists of actual constructors and notional constructors that result from the transformation of defaulted parameters as follows:
[list of cases omitted]
4 A constructor so declared has the same access as the corresponding constructor in X. It is deleted if the corresponding constructor in
Xis deleted (8.4).
You can call it directly of course:
TestableFoo(int i) : Foo(i) { }
回答2:
This behaviour is conform with what the standard says (ISO/IEC 14822:2011 12.9, §4) :
A constructor so declared has the same access as the corresponding constructor in X.
where X is the base class from which the constructors are inherited.
To get the desired behaviour, you can use :
class TestableFoo : public Foo {
public :
TestableFoo(int i) : Foo(i) { }
using Foo::run;
};
来源:https://stackoverflow.com/questions/24635935/use-of-using-keyword-to-make-inherited-constructor-public