Private inheritance question 
October 10th, 2005, 10:25 PM
| | | Private inheritance question
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:
class A
{
};
class B : private A
{
};
class C : public B
{
public:
// error here
void Func(A& a);
}
The error from the compiler is "'A' not accessible because 'B' uses
'private' to inherit from 'A'"
When I contacted the vendor's support about this I got the response:
"This is the way C++ works. The use of private inheritance turns all
non-private members of the base class into private members of the derived
class, and disallows all standard conversions between derived to base . This
construction
void Func(::A& a);
will work"
And he's right, it does work. I'm just wondering - what is the error in my
original construct? I can't see where the "conversion" that the response
refers to is. I'm not trying to convert anything from derived to base. I
simply have a function in the derived class to which I am passing a
parameter of the same type as the base class.
Thanks,
Jon | 
October 10th, 2005, 10:35 PM
| | | Re: Private inheritance question
* Jonathan Potter:[color=blue]
> 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:
>
> class A
> {
> };
>
> class B : private A
> {
> };
>
> class C : public B
> {
> public:
> // error here
> void Func(A& a);
> }
>
>
> The error from the compiler is "'A' not accessible because 'B' uses
> 'private' to inherit from 'A'"
>
> When I contacted the vendor's support about this I got the response:
>
> "This is the way C++ works. The use of private inheritance turns all
> non-private members of the base class into private members of the derived
> class, and disallows all standard conversions between derived to base . This
> construction
>
> void Func(::A& a);
>
> will work"
>
> And he's right, it does work. I'm just wondering - what is the error in my
> original construct? I can't see where the "conversion" that the response
> refers to is.[/color]
You've focused on the wrong part of the answer -- that's just supplementary
information. The important part is that A is a private member of B. In C you
were trying to access that private member because lookup of the unqualified A
finds members first.
--
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? | 
October 10th, 2005, 10:45 PM
| | | Re: Private inheritance question
Jonathan Potter wrote:[color=blue]
> 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:
>
> class A
> {
> };
>
> class B : private A
> {
> };
>
> class C : public B
> {
> public:
> // error here
> void Func(A& a);[/color]
'A' is inaccessible (private) base of 'B'. The name is visible, the
access is prohibited.
[color=blue]
> }[/color]
;
[color=blue]
>
>
> The error from the compiler is "'A' not accessible because 'B' uses
> 'private' to inherit from 'A'"
>
> When I contacted the vendor's support about this I got the response:
>
> "This is the way C++ works. The use of private inheritance turns all
> non-private members of the base class into private members of the derived
> class, and disallows all standard conversions between derived to base . This
> construction
>
> void Func(::A& a);
>
> will work"
>
> And he's right, it does work. I'm just wondering - what is the error in my
> original construct?[/color]
'A' _inside_ 'C' refers to 'B::A', which is private.
[color=blue]
> I can't see where the "conversion" that the response
> refers to is. I'm not trying to convert anything from derived to base. I
> simply have a function in the derived class to which I am passing a
> parameter of the same type as the base class.[/color]
Name lookup for an unqualified name 'A' finds '::C::B::A' and prefers it
over '::A'.
V | 
October 10th, 2005, 11:45 PM
| | | Re: Private inheritance question
Ah! Thank you both. That makes perfect sense!
So actually the fact that this code used to compile in the old compiler
(Visual C++ 6.0) was presumably an error in the first place?
"Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
news:EYB2f.40045$Tf5.25880@newsread1.mlpsca01.us.t o.verio.net...[color=blue]
>
> Name lookup for an unqualified name 'A' finds '::C::B::A' and prefers it
> over '::A'.[/color]
"Alf P. Steinbach" <alfps@start.no> wrote in message
news:434ae95b.44694765@news.individual.net...[color=blue]
>
> You've focused on the wrong part of the answer -- that's just
> supplementary
> information. The important part is that A is a private member of B. In C
> you
> were trying to access that private member because lookup of the
> unqualified A
> finds members first.[/color] | 
October 11th, 2005, 01:15 AM
| | | Re: Private inheritance question
Victor Bazarov wrote:[color=blue]
> Jonathan Potter wrote:[color=green]
> > 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:
> >
> > class A
> > {
> > };
> >
> > class B : private A
> > {
> > };
> >
> > class C : public B
> > {
> > public:
> > // error here
> > void Func(A& a);[/color]
>
> 'A' is inaccessible (private) base of 'B'. The name is visible, the
> access is prohibited.
>[color=green]
> > }[/color]
> ;
>[color=green]
> >
> >
> > The error from the compiler is "'A' not accessible because 'B' uses
> > 'private' to inherit from 'A'"
> >
> > When I contacted the vendor's support about this I got the response:
> >
> > "This is the way C++ works. The use of private inheritance turns all
> > non-private members of the base class into private members of the derived
> > class, and disallows all standard conversions between derived to base . This
> > construction
> >
> > void Func(::A& a);
> >
> > will work"
> >
> > And he's right, it does work. I'm just wondering - what is the error in my
> > original construct?[/color]
>
> 'A' _inside_ 'C' refers to 'B::A', which is private.
>[color=green]
> > I can't see where the "conversion" that the response
> > refers to is. I'm not trying to convert anything from derived to base. I
> > simply have a function in the derived class to which I am passing a
> > parameter of the same type as the base class.[/color]
>
> Name lookup for an unqualified name 'A' finds '::C::B::A' and prefers it
> over '::A'.[/color]
I would characterize the behavior slightly differently: the compiler
prefers "::C::B::A" because it finds it first. Once the C++ compiler
finds a declaration to match a name, it stops looking for any other
matching declarations, including declarations for the same symbol that
may offer a different level of access.
So whatever the access restriction is on the first declaration found,
is the access level that the compiler will apply to the name when it
appears in the source code. In this case the global namespace specifier
ensures that the compiler will find ::A first because it ensures that
the compiler will be looking only in the global namespace for A.
Greg | 
October 11th, 2005, 02:05 PM
| | | Re: Private inheritance question
Greg wrote:[color=blue]
> [...]
> I would characterize the behavior slightly differently: the compiler
> prefers "::C::B::A" because it finds it first.[/color]
Yes and no. The compiler finds all of them. However, if a member with
that name exists, the other names are discarded (not considered). If
they were equally considered, there would be ambiguity (before checking
access specifiers). Of course, we could say that it finds the member
first (and stops looking for others) if we can prove (or assume) that the
compiler looks for members first.
[color=blue]
> Once the C++ compiler
> finds a declaration to match a name, it stops looking for any other
> matching declarations, including declarations for the same symbol that
> may offer a different level of access.
>
> So whatever the access restriction is on the first declaration found,
> is the access level that the compiler will apply to the name when it
> appears in the source code. In this case the global namespace specifier
> ensures that the compiler will find ::A first because it ensures that
> the compiler will be looking only in the global namespace for A.[/color]
V | 
October 12th, 2005, 02:05 PM
| | | Re: Private inheritance question
Victor Bazarov wrote:[color=blue]
> Greg wrote:[color=green]
> > [...]
> > I would characterize the behavior slightly differently: the compiler
> > prefers "::C::B::A" because it finds it first.[/color]
>
> Yes and no. The compiler finds all of them. However, if a member with
> that name exists, the other names are discarded (not considered). If
> they were equally considered, there would be ambiguity (before checking
> access specifiers). Of course, we could say that it finds the member
> first (and stops looking for others) if we can prove (or assume) that the
> compiler looks for members first.[/color]
Only when searching for a function declaration is the compiler's search
exhaustive. For other types of names, including those in this example,
the compiler follows this rule:
"In all cases listed in 3.4.1, the scopes are searched for a
declaration in the order listed in each of the respective categories;
name lookup ends a soon as a declaration is found for the name. If no
declaration is found, the program is ill-formed." §3.4.1/1
I should clarify that the compiler when searching a particular scope
always searches that scope completely. In this way, names duplicated in
different declarations within the same scope prompt an error - while
names declared in one scope tend to "hide" duplicate names declared in
more distant scopes.
Greg | | Thread Tools | Search this Thread | | | |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 220,840 network members.
|