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

Access of base class' private base class: qualification required, why

#include <iostream>

struct Belcher
{
int x;
void belch() { std::cout << x << std::endl; }
Belcher( int anX ): x( anX ) {}
};

struct Person: private Belcher { Person(): Belcher( 666 ) {} };

struct Viking: Person
{
void eat() {}
void dine( bool belch )
{
eat();
if( belch )
{
Viking* pv = this;
::Belcher* p = (::Belcher*) pv;
// Why is qualification necessary here?
}
}
};

int main()
{
Viking v;
Viking* pv = &v;
Belcher* p = (Belcher*) pv;
p->belch();
}

--
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 3 '05 #1
6 1665
Alf P. Steinbach wrote:
#include <iostream>

struct Belcher
{
int x;
void belch() { std::cout << x << std::endl; }
Belcher( int anX ): x( anX ) {}
};

struct Person: private Belcher { Person(): Belcher( 666 ) {} };

struct Viking: Person
{
void eat() {}
void dine( bool belch )
{
eat();
if( belch )
{
Viking* pv = this;
::Belcher* p = (::Belcher*) pv;
// Why is qualification necessary here?
By qualifying you explicitly specify to use the global name 'Belcher'
not the 'Belcher' name brought into the scope of this class from the
Person's scope -- the grandfather class. If you remember, a name in
scope _hides_ the name in the enclosing scope. 'Belcher' in 'Viking'
comes from 'Person' and in 'Person' it hides '::Belcher'.

I am a bit perplexed by the need to do that C-style cast. If the base
class is private, you're not supposed to use it. Why force the code
into doing something that is purposely not there?
}
}
};

int main()
{
Viking v;
Viking* pv = &v;
Belcher* p = (Belcher*) pv;
p->belch();
}


V
Sep 3 '05 #2
* Victor Bazarov:
Alf P. Steinbach wrote:
#include <iostream>

struct Belcher
{
int x;
void belch() { std::cout << x << std::endl; }
Belcher( int anX ): x( anX ) {}
};

struct Person: private Belcher { Person(): Belcher( 666 ) {} };

struct Viking: Person
{
void eat() {}
void dine( bool belch )
{
eat();
if( belch )
{
Viking* pv = this;
::Belcher* p = (::Belcher*) pv;
// Why is qualification necessary here?
By qualifying you explicitly specify to use the global name 'Belcher'
not the 'Belcher' name brought into the scope of this class from the
Person's scope -- the grandfather class. If you remember, a name in
scope _hides_ the name in the enclosing scope.


Well, yes, but it isn't really in scope in Viking when it's private in
Person, is it? I mean, that's an implementation detail of Person. It
shouldn't affect Viking, except for virtual member functions.

'Belcher' in 'Viking'
comes from 'Person' and in 'Person' it hides '::Belcher'.

I am a bit perplexed by the need to do that C-style cast. If the base
class is private, you're not supposed to use it. Why force the code
into doing something that is purposely not there?


Just to do the C cast...

--
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 3 '05 #3
"Alf P. Steinbach" <al***@start.no> wrote in message
news:43*****************@news.individual.net
* Victor Bazarov:
Alf P. Steinbach wrote:
#include <iostream>

struct Belcher
{
int x;
void belch() { std::cout << x << std::endl; }
Belcher( int anX ): x( anX ) {}
};

struct Person: private Belcher { Person(): Belcher( 666 ) {} };

struct Viking: Person
{
void eat() {}
void dine( bool belch )
{
eat();
if( belch )
{
Viking* pv = this;
::Belcher* p = (::Belcher*) pv;
// Why is qualification necessary here?


By qualifying you explicitly specify to use the global name 'Belcher'
not the 'Belcher' name brought into the scope of this class from the
Person's scope -- the grandfather class. If you remember, a name in
scope _hides_ the name in the enclosing scope.


Well, yes, but it isn't really in scope in Viking when it's private in
Person, is it? I mean, that's an implementation detail of Person. It
shouldn't affect Viking, except for virtual member functions.


By 10.2, name lookup takes place before access control. If I have
interpreted this correctly, this means that the fact that Belcher is private
in Person is irrelevant for name lookup purposes.

What surprises me is that inheriting from Belcher apparently has the effect
of declaring a Belcher type that is distinct from the Belcher type declared
at global scope. But I guess this makes sense; after all a base subobject
can be of zero size, whereas a free-standing object of the same-named class
cannot be of zero size.
--
John Carson

Sep 3 '05 #4
John Carson wrote:
[...]
What surprises me is that inheriting from Belcher apparently has the
effect of declaring a Belcher type that is distinct from the Belcher
type declared at global scope.
Why does that surprise you?

3.4/3 says that the name of the class is a member of that class for
the purposes of name lookup. Since all members are inherited (unless
they are hidden), the name of any base class is considered a member
of the derived class. If you inherit the derived class again, the
member of it will become a member of the next derived class and so on.
But I guess this makes sense; after
all a base subobject can be of zero size, whereas a free-standing
object of the same-named class cannot be of zero size.


I am not sure how you stitch sizes into that... It's simpler.

class A {};

class B { // I purposely didn't inherit B from A
typedef A A; // that was happens if inherited; choose your
// access specifier. 'A' is now a member of 'B'
};

class C : B {
// A is a member here too
};

int main() {
A a; // OK
B::A ba; // cannot access private name
C::A ca; // same error
}

V
Sep 3 '05 #5
* Victor Bazarov:
John Carson wrote:
[...]
What surprises me is that inheriting from Belcher apparently has the
effect of declaring a Belcher type that is distinct from the Belcher
type declared at global scope.


Why does that surprise you?

3.4/3 says that the name of the class is a member of that class for
the purposes of name lookup. Since all members are inherited (unless
they are hidden), the name of any base class is considered a member
of the derived class. If you inherit the derived class again, the
member of it will become a member of the next derived class and so on.
But I guess this makes sense; after
all a base subobject can be of zero size, whereas a free-standing
object of the same-named class cannot be of zero size.


I am not sure how you stitch sizes into that... It's simpler.

class A {};

class B { // I purposely didn't inherit B from A
typedef A A; // that was happens if inherited; choose your
// access specifier. 'A' is now a member of 'B'
};

class C : B {
// A is a member here too
};

int main() {
A a; // OK
B::A ba; // cannot access private name
C::A ca; // same error
}


Thanks Victor, you cleared this up, and my frust-o-meter is now starting to
calm down. :-)

--
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 3 '05 #6
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:pt********************@comcast.com
John Carson wrote:
[...]
What surprises me is that inheriting from Belcher apparently has the
effect of declaring a Belcher type that is distinct from the Belcher
type declared at global scope.
Why does that surprise you?


Sheer ignorance on my part Victor.
3.4/3 says that the name of the class is a member of that class for
the purposes of name lookup. Since all members are inherited (unless
they are hidden), the name of any base class is considered a member
of the derived class. If you inherit the derived class again, the
member of it will become a member of the next derived class and so on.


I hunted around for a section such as you cite, but couldn't find it. Thanks
for the info.
--
John Carson

Sep 3 '05 #7

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

Similar topics

25
by: John Harrison | last post by:
This code fails to compile on Comeau C++ and VC++ 7.1 (with language extensions disabled) template <class T> struct B { T b; }; template <class T>
1
by: Dave | last post by:
Hello NG, Regarding access-declarations and member using-declarations as used to change the access level of an inherited base member... Two things need to be considered when determining an...
10
by: Clint | last post by:
Hey all - I'm having a really confusing problem concerning a web service. Right now, I have an application that needs to call a web service that does nothing but return "true" (this will...
1
by: Murray Gill | last post by:
Our current solution has a number of ASP.NET pages with very similar functionality. We would like to move the common functions into a base class that inherits from System.Web.UI.Page, and then force...
29
by: Patrick | last post by:
I have the following code, which regardless which works fine and logs to the EventViewer regardless of whether <processModel/> section of machine.config is set to username="SYSTEM" or "machine" ...
3
by: Mr Newbie | last post by:
I am messing around with Web User Controls at present and (think) I have discovered the following. 1.) The identifier for the control in the code behind must match the ID for the control on the...
6
by: Dave Rahardja | last post by:
Is it safe to use static_cast to downcast from a virtual base class? For example, class V {}; class A: public virtual V {}; class B: public virtual V {}; class C: public A, public B; void...
0
by: bharathreddy | last post by:
Here I will given an example on how to access the session, application and querystring variables in an .cs class file. Using System.Web.HttpContext class. 1) For accesing session variables :...
6
by: Wesley Peace | last post by:
I hate to cross post, but I've gotten no answer yet on a problem I'm having with visual studio 2008. I've created a series of forms with controls to access a Access database tables. The...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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...

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.