473,434 Members | 1,390 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,434 software developers and data experts.

Private inheritance renders class inaccessible

The following code does not compile:

class X {};

class Y : private X {};

class Z : public Y
{
public:
Z(X&) {} // problem here
};

Both GCC 3.3 and Comeau Online give the same error:

test.cpp: In constructor `Z::Z(X&)':
test.cpp:1: error: `class X' is inaccessible
test.cpp:8: error: within this context

I can fix the error by changing the broken ctor to Z(::X&) to
explicitly refer to the global class ::X, but I don't understand why I
have to. Can someone explain why private inheritance makes X
inaccessible in this situation?

Thanks.

Sep 23 '05 #1
7 3488
* sp**@grog.net:
The following code does not compile:

class X {};

class Y : private X {};

class Z : public Y
{
public:
Z(X&) {} // problem here
};

Both GCC 3.3 and Comeau Online give the same error:

test.cpp: In constructor `Z::Z(X&)':
test.cpp:1: error: `class X' is inaccessible
test.cpp:8: error: within this context

I can fix the error by changing the broken ctor to Z(::X&) to
explicitly refer to the global class ::X, but I don't understand why I
have to. Can someone explain why private inheritance makes X
inaccessible in this situation?


It's not obvious. But last time we rehashed this in this group (I posed the
question, just as mystified as you probably are) a natural explanation was
provided by Victor Bazarov, I think it was. Namely that the inheritance for Y
introduces the name X in the class, and ordinary access rules apply when
referring to X that way -- as a name in the class. Qualifying X,
essentially referring to it via another route, fixes that. I can sort of
understand how that results from the detailed technical rules, but I think
that if that explanation is correct, and nothing so far has indicated that it
could be incorrect, then it's a language design bug... ;-)

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Sep 23 '05 #2
sp**@grog.net wrote:
The following code does not compile:

class X {};

class Y : private X {};

class Z : public Y
{
public:
Z(X&) {} // problem here
};

Both GCC 3.3 and Comeau Online give the same error:

test.cpp: In constructor `Z::Z(X&)':
test.cpp:1: error: `class X' is inaccessible
test.cpp:8: error: within this context

I can fix the error by changing the broken ctor to Z(::X&) to
explicitly refer to the global class ::X, but I don't understand why I
have to. Can someone explain why private inheritance makes X
inaccessible in this situation?


The name 'X' (without qualification) is inserted into class X's scope when
you define it. That name becomes a member for the purposes of name
lookup. In 'Y' that member is _inherited_, but made *private*. In 'Z' it
is inherited again, but is inaccessible.

Now, when you qualify the name (by means of the name resolution operator,
colon-colon), you issue an explicit instruction to your compiler as to
which 'X' out of two (one in the global scope and the other in the class
scope) to choose. Since the global one is accessible, you have no problem
like with the member. According to name lookup rules, however, the member
is preferred when an unqualified name is used.

V
Sep 23 '05 #3
Alf P. Steinbach wrote:
[...] Namely that the inheritance for Y
introduces the name X in the class,
Actually 'X' has its own name as a member, 'Y' just inherits it.
Relevant clause is 9, paragraph 2.
[..]


V
Sep 23 '05 #4
Thanks Victor. I won't pretend this is obvious, but I the reasoning
makes sense.

Sep 23 '05 #5
Victor Bazarov wrote:
sp**@grog.net wrote:
The following code does not compile:

class X {};

class Y : private X {};

class Z : public Y
{
public:
Z(X&) {} // problem here
};

Both GCC 3.3 and Comeau Online give the same error:

test.cpp: In constructor `Z::Z(X&)':
test.cpp:1: error: `class X' is inaccessible
test.cpp:8: error: within this context

I can fix the error by changing the broken ctor to Z(::X&) to
explicitly refer to the global class ::X, but I don't understand why I
have to. Can someone explain why private inheritance makes X
inaccessible in this situation?

The name 'X' (without qualification) is inserted into class X's scope when
you define it. That name becomes a member for the purposes of name
lookup. In 'Y' that member is _inherited_, but made *private*. In 'Z' it
is inherited again, but is inaccessible.

Now, when you qualify the name (by means of the name resolution operator,
colon-colon), you issue an explicit instruction to your compiler as to
which 'X' out of two (one in the global scope and the other in the class
scope) to choose. Since the global one is accessible, you have no problem
like with the member. According to name lookup rules, however, the member
is preferred when an unqualified name is used.

V


Am I way off the mark in thinking that is similar in spirit to the
situation where, for example, defining a function foo() in a derived
class hides not only foo() in the base class but any other overloaded
versions of foo (say, foo(int)) in the base class too?

It seems that C++ is at least consistent here, in that it stops looking
for a name as soon as it finds it in any scope, even if the found
instance is not appropriate/useful/sensible.

As to motivation (which someone else brought up elsewhere in this
thread), I've seen it argued that this is sensible behavior in the case
of function overloading as it prevents a deeply derived class from
accidentally invoking a function about whose existence it is perhaps
unaware. Can the same argument be made in this case?

Mark
Sep 24 '05 #6
Mark P wrote:
[...]
Am I way off the mark in thinking that is similar in spirit to the
situation where, for example, defining a function foo() in a derived
class hides not only foo() in the base class but any other overloaded
versions of foo (say, foo(int)) in the base class too?
Name hides another name. Arguments have nothing to do with it.
'foo' member function in a derived class would hide 'foo' data member
just as well.
It seems that C++ is at least consistent here, in that it stops
looking for a name as soon as it finds it in any scope, even if the
found instance is not appropriate/useful/sensible.
That is not always so. The rules aren't that simple, anyway.
As to motivation (which someone else brought up elsewhere in this
thread), I've seen it argued that this is sensible behavior in the
case of function overloading as it prevents a deeply derived class
from accidentally invoking a function about whose existence it is
perhaps unaware. Can the same argument be made in this case?


Generally speaking, you're correct. The big deal would be if the
meaning (or the behaviour) of the "other" X (or foo) changed, there
should be no effect on the class who defines its own. Now, whether
it applies here I am not sure, but straight-forwardness of name
lookup is probably important.

V
Sep 24 '05 #7
<sp**@grog.net> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
The following code does not compile:

class X {};

class Y : private X {};

class Z : public Y
{
public:
Z(X&) {} // problem here
};

Both GCC 3.3 and Comeau Online give the same error:

test.cpp: In constructor `Z::Z(X&)':
test.cpp:1: error: `class X' is inaccessible
test.cpp:8: error: within this context


By using private inheritance, you're telling the compiler you DON'T
want classes derived from Y to have access to their "X" part.

If you want to allow classes derived from Y to access their own
"X" part, you could use protected inheritance instead:

class X
{

};

class Y : protected X
{

};

class Z : public Y
{
public:
Z(X&) {}
};

int main()
{
return 0;
}

You'll find that compiles and runs without error.

--
Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant

Sep 24 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Dave Theese | last post by:
Hello all, The example below demonstrates proper conformance to the C++ standard. However, I'm having a hard time getting my brain around which language rules make this proper... The error...
8
by: Dave | last post by:
Hello all, Suppose that derived inherits privately from base. A base pointer may not be made to point at a derived object in this case. I understand that is exactly what is supposed to happen...
19
by: qazmlp | last post by:
class base { // other members public: virtual ~base() { } virtual void virtualMethod1()=0 ; virtual void virtualMethod2()=0 ; virtual void virtualMethod3()=0 ;
10
by: Ioannis Vranos | last post by:
May someone explain why does this compile? class HiddenSealBaseClass { public: HiddenSealBaseClass() { } }; class Sealed: virtual HiddenSealBaseClass
2
by: MJ | last post by:
Hi I have a following sample code class base and class derived. I have inherited the base class as private and tried to compile the code its giving an error "conversion from 'class derived *' to...
6
by: Jonathan Potter | last post by:
Hi, I was wondering if someone could explain something to me. We recently upgraded to a new C++ compiler and found some old code wouldn't compile. Boiled down, the code that causes the error is:...
8
by: __PPS__ | last post by:
Hello everybody, today I had another quiz question "if class X is privately derived from base class Y what is the scope of the public, protected, private members of Y will be in class X" By...
3
by: bob | last post by:
is this true of private inheritance? public stuff becomes private private stuff becomes inaccessible to the new class protected stays protected and is accessible to the new class
4
by: zhangyefei.yefei | last post by:
i read book <effective c++>,it tell me that public inheritance means is-a ,and private inheritance means is-implemented-in-terms-of. but today i am puzzled by some strange codes. the...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.