Reputation: 73
class Base
{
public: void foo(){}
};
class Derived : public Base
{
private:
using Base::foo;
};
int main()
{
Derived d;
d.foo();
}
Is the code legal? The declaration using Base::foo
is in the private section of the derived class. So the call d.foo()
shouldn't compile, am I right?
Upvotes: 7
Views: 1658
Reputation: 92864
The Standard in section 11.2/4 says
A member m is accessible when named in class N if
— m as a member of N is public, or
— m as a member of N is private, and the reference occurs in a member or friend of class N, or
— m as a member of N is protected, and the reference occurs in a member or friend of class N, or in a member or friend of a class P derived from N, where m as a member of P is private or protected, or
— there exists a base class B of N that is accessible at the point of reference, and m is accessible when named in class B.
However the Standard also says that
§11.3/1 "The access of a member of a base class can be changed in the derived class.
In your code the access of the member foo
has been changed in the derived class. So the code shouldn't compile but this is still an active issue with open status So some compilers compile the code (Comeau and Intel C++) whereas g++ and MSVC++ (correctly) reject it.
Upvotes: 1
Reputation: 3021
using
is a namespace declaration in this example (as opposed to a namespace directive). It is not a method declaration, as you seem to be intending to use it as.
The method foo()
is public in the Base
class, and is still accessible in the Derived
class.
You seem to be intending to make the foo()
of the Base
class inaccessible. Although there might be a way to do this (I wouldn't know, I've never had a reason to attempt it), I suggest that this points out an error with the logic of your inheritance, and you may want to consider redesigning y our classes.
If your Derived
class isn't going to behave as a Base
class, it shouldn't inherit from a Base
class.
Upvotes: 0
Reputation: 145269
Right.
Now reality check…
MinGW g++ 4.4.1:
x.cpp: In function 'int main()': x.cpp:3: error: 'void Base::foo()' is inaccessible
x.cpp:15: error: within this context
Visual C++ 10.0:
x.cpp(15) : error C2248: 'Derived::foo' : cannot access private member declared in class 'Derived'
x.cpp(9) : see declaration of 'Derived::foo'
x.cpp(6) : see declaration of 'Derived'
Comeau Online 4.3.10.1:
In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link).
Compiled with C++0x extensions enabled.
Oops. And Comeau is the one that's nearly always right! Well, turning off C++0x extensions, for C++98/C++03:
In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link).
Compiled with C++0x extensions DISabled.
Oops!
Well, you biggie mine, as they say in Norway (literally translated to English).
I'd try to report that to Comeau.
EDIT: since Prasoon has also answered, quoting the Holy Standard with his interpretation of that contradicting what I wrote above, well, OK, standadeese…
§11.3/1 "The access of a member of a base class can be changed in the derived class…", and so on, which is as clear as can be (no interpretation required). And with a concrete example. And normative text stating that that is equivalent to a using
declaration.
Cheers & hth.,
Upvotes: 5