473,394 Members | 1,800 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,394 software developers and data experts.

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
Oct 10 '05 #1
6 5063
* Jonathan Potter:
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.


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?
Oct 10 '05 #2
Jonathan Potter wrote:
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);
'A' is inaccessible (private) base of 'B'. The name is visible, the
access is prohibited.
} ;


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?
'A' _inside_ 'C' refers to 'B::A', which is private.
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.


Name lookup for an unqualified name 'A' finds '::C::B::A' and prefers it
over '::A'.

V
Oct 10 '05 #3
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.********@comAcast.net> wrote in message
news:EY*******************@newsread1.mlpsca01.us.t o.verio.net...

Name lookup for an unqualified name 'A' finds '::C::B::A' and prefers it
over '::A'.
"Alf P. Steinbach" <al***@start.no> wrote in message
news:43***************@news.individual.net...
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.

Oct 10 '05 #4
Victor Bazarov wrote:
Jonathan Potter wrote:
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);


'A' is inaccessible (private) base of 'B'. The name is visible, the
access is prohibited.
}

;


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?


'A' _inside_ 'C' refers to 'B::A', which is private.
> 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.


Name lookup for an unqualified name 'A' finds '::C::B::A' and prefers it
over '::A'.


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

Oct 11 '05 #5
Greg wrote:
[...]
I would characterize the behavior slightly differently: the compiler
prefers "::C::B::A" because it finds it first.
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.
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.


V
Oct 11 '05 #6
Victor Bazarov wrote:
Greg wrote:
[...]
I would characterize the behavior slightly differently: the compiler
prefers "::C::B::A" because it finds it first.


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.


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

Oct 12 '05 #7

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...
3
by: seesaw | last post by:
Compared to "public", how does "private/protected" in inheritance change relationship between classes what is the purpose to define constructor as "private/protected"? is there any usage to...
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...
1
by: Tony Johansson | last post by:
Hello! Private inheritance is sometimes called implementation inheritance. If you use this private inheritance how is with the usage of overriding then. Is overriding used less often when...
7
by: spam | last post by:
The following code does not compile: class X {}; class Y : private X {}; class Z : public Y { public: Z(X&) {} // problem here
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...
6
by: karthikbalaguru | last post by:
Hi, Could someone here tell me some links/pdfs/tutorials to know about the difference between Private Inheritance and Public Inheritance ? I am unable to get info w.r.t it. Thx in advans,...
8
by: puzzlecracker | last post by:
The statement is taken from FAQ . What about non-virtual functions? Can they be overriden? I still don't see a good justification to prefer private inheritance over composition. In fact, I have...
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...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
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
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

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.