JKS
JKS

Reputation: 73

Access to base class function

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

Answers (3)

Prasoon Saurav
Prasoon Saurav

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

KevenK
KevenK

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

Cheers and hth. - Alf
Cheers and hth. - Alf

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

Related Questions