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

class acces scope weirdness

Hi,

I am not sure if I have found a compiler bug (I am using VC++.NET2003)
or if this is the correct behavior defined by the language but I am
sure someone can clear up my confusion. Suppose the following:

class Base
{
protected:
int x;
};

class Derived : public Base
{
public:
void A( const Derived &d )
{ x = d.x; // Ok }
void B( const Base &b )
{ x = b.x; //Error: cannot access protected member declared in
class 'Base' }
};

What is the problem with B()? What should I change in Derived to fix
the problem? The best thing I came up is by modifying Base like this:

class Base
{
protected:
void SetX(const Base &b) { x = b.x; }
int x;
};

and call SetX from B().

Thanks,
Olivier Langlois
http://www3.sympatico.ca/olanglois
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

May 23 '06 #1
9 1868
ol*******@sympatico.ca wrote:
I am not sure if I have found a compiler bug (I am using VC++.NET2003)
No.
or if this is the correct behavior defined by the language
Yes.
but I am
sure someone can clear up my confusion. Suppose the following:

class Base
{
protected:
int x;
};

class Derived : public Base
{
public:
void A( const Derived &d )
{ x = d.x; // Ok }
void B( const Base &b )
{ x = b.x; //Error: cannot access protected member declared in
class 'Base' }
Correct behaviour.
};

What is the problem with B()? What should I change in Derived to fix
the problem?
Nothing. The derived class cannot access protected members in objects
of other than its own type.
The best thing I came up is by modifying Base like this:

class Base
{
protected:
void SetX(const Base &b) { x = b.x; }
int x;
};

and call SetX from B().


That's it. As you can see, you can't do it in Derived.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 23 '06 #2

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:e4**********@news.datemas.de...
ol*******@sympatico.ca wrote:
I am not sure if I have found a compiler bug (I am using VC++.NET2003)


No.
or if this is the correct behavior defined by the language


Yes.
but I am
sure someone can clear up my confusion. Suppose the following:

class Base
{
protected:
int x;
};

class Derived : public Base
{
public:
void A( const Derived &d )
{ x = d.x; // Ok }
void B( const Base &b )
{ x = b.x; //Error: cannot access protected member declared in
class 'Base' }


Correct behaviour.
};

What is the problem with B()? What should I change in Derived to fix
the problem?


Nothing. The derived class cannot access protected members in objects
of other than its own type.


I was curious about this and looked up the protected keyword in MSDN and
came across this:

The protected keyword specifies access to class members in the member-list
up to the next access specifier (public or private) or the end of the class
definition. Class members declared as protected can be used only by the
following:

Member functions of the class that originally declared these members.
Friends of the class that originally declared these members.
Classes derived with public or protected access from the class that
originally declared these members.
Direct privately derived classes that also have private access to protected
members.

Is MSDN wrong or am I reading it wrong? It seems to state that "...can be
used only by the following: ... Classes derived with public or protected
access from the class that originally declared these members..."

Isn't that the case here? Isn't Derived deriving with public access from
Base? I'm not sure since I never use protected.
May 23 '06 #3
Jim Langston wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:e4**********@news.datemas.de...
ol*******@sympatico.ca wrote:
I am not sure if I have found a compiler bug (I am using
VC++.NET2003)
No.
or if this is the correct behavior defined by the language


Yes.
but I am
sure someone can clear up my confusion. Suppose the following:

class Base
{
protected:
int x;
};

class Derived : public Base
{
public:
void A( const Derived &d )
{ x = d.x; // Ok }
void B( const Base &b )
{ x = b.x; //Error: cannot access protected member declared in
class 'Base' }


Correct behaviour.
};

What is the problem with B()? What should I change in Derived to fix
the problem?


Nothing. The derived class cannot access protected members in
objects of other than its own type.


I was curious about this and looked up the protected keyword in MSDN
and came across this:

The protected keyword specifies access to class members in the
member-list up to the next access specifier (public or private) or
the end of the class definition. Class members declared as protected
can be used only by the following:

Member functions of the class that originally declared these members.
Friends of the class that originally declared these members.
Classes derived with public or protected access from the class that
originally declared these members.
Direct privately derived classes that also have private access to
protected members.

Is MSDN wrong or am I reading it wrong?


MSDN's description is incomplete. Does it mean it's wrong? I don't
know.

An object can only access protected members of the object of its own
type. From 11.5/1:

"When a friend or a member function of a derived class references
a protected nonstatic member function or
protected nonstatic data member of a base class, an access check
applies in addition to those described earlier
in clause 11.102) Except when forming a pointer to member (5.3.1),
the access must be through a
pointer to, reference to, or object of the derived class itself
(or any class derived from that class) (5.2.5)."

See the "must be through a pointer to, reference to, or object of
the defiend class itself"?
It seems to state that
"...can be used only by the following: ... Classes derived with
public or protected access from the class that originally declared
these members..."
Isn't that the case here? Isn't Derived deriving with public access
from Base? I'm not sure since I never use protected.


It's not the case here. The object '*this' is trying to access the
'x' protected member in an object of type 'Base', IOW in an object
of another type than its own.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 23 '06 #4

ol*******@sympatico.ca wrote:
Hi,

I am not sure if I have found a compiler bug (I am using VC++.NET2003)
or if this is the correct behavior defined by the language but I am
sure someone can clear up my confusion. Suppose the following:

class Base
{
protected:
int x;
};

class Derived : public Base
{
public:
void A( const Derived &d )
{ x = d.x; // Ok }
void B( const Base &b )
{ x = b.x; //Error: cannot access protected member declared in
class 'Base' }
};

What is the problem with B()? What should I change in Derived to fix
the problem? The best thing I came up is by modifying Base like this:

class Base
{
protected:
void SetX(const Base &b) { x = b.x; }
int x;
};

and call SetX from B().

Thanks,
Olivier Langlois
http://www3.sympatico.ca/olanglois


I think the SetX() should work only if it's made public. Same with the
x attribute.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

May 23 '06 #5

ol*******@sympatico.ca wrote:

I am not sure if I have found a compiler bug (I am using VC++.NET2003)
or if this is the correct behavior defined by the language but I am
sure someone can clear up my confusion. Suppose the following:
The compiler is correct in this regard.

class Base
{
protected:
int x;
};

class Derived : public Base
{
public:
void A( const Derived &d )
{ x = d.x; // Ok }
void B( const Base &b )
{ x = b.x; //Error: cannot access protected member declared in
class 'Base' }
};

What is the problem with B()? What should I change in Derived to fix
the problem?


Nothing.

If class Derived were allowed to access data member x of any Base object, the
access control provided by protected could be subverted by deriving another
class from Base just for this purpose.

I.e.

void foo1(Base &b)
{
b.x; // oops, data member x is protected
}

So let's do

void foo2(Base &b)
{
struct MyHack : Base // derived from Base to hijack access to B::x
{
static void bar(Base &b)
{
b.x; // would be correct if MyHack could access x of any Base object
}
};

MyHack::bar(b);
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

May 24 '06 #6
* ol*******@sympatico.ca:
Hi,

I am not sure if I have found a compiler bug (I am using VC++.NET2003)
or if this is the correct behavior defined by the language but I am
sure someone can clear up my confusion. Suppose the following:

class Base
{
protected:
int x;
};

class Derived : public Base
{
public:
void A( const Derived &d )
{ x = d.x; // Ok }
void B( const Base &b )
{ x = b.x; //Error: cannot access protected member declared in
class 'Base' }
};

What is the problem with B()?
The standard prohibits that access.

Reason: if it were allowed, all you'd need to do to access protected
class X members in any object would be to derive a class from X.

What should I change in Derived to fix the problem?


It's not a problem, it's a feature... ;-)

Seriously, you haven't described the /problem/ you're trying to solve,
only a flawed attempt at a solution.

But one may speculate that the problem is how to initialize members of
Base, and if so, then the answer is, in general, to provide an
appropriate Base constructor, or more.

--
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?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

May 24 '06 #7
> class Derived : public Base
{
public:
void A( const Derived &d )
{ x = d.x; // Ok }
void B( const Base &b )
{ x = b.x; //Error: cannot access protected member declared in
class 'Base' }

};

What is the problem with B()? What should I change in Derived to fix
the problem? The best thing I came up is by modifying Base like this:


The compiler is correct. When a base class has protected data, it
only allows a derived type to access protected data of instances of
that derived type. It does not grant unrestricted access to the
protected data of EVERY derived type. When you only have a reference
to the base, the actual object might not be a Derived, but maybe
something else that is derived from Base. Derived should NOT have
access to another derived types's protected data simply because they
both have the same base class.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

May 24 '06 #8
ol*******@sympatico.ca wrote:
Hi,

I am not sure if I have found a compiler bug (I am using VC++.NET2003)
or if this is the correct behavior defined by the language but I am
sure someone can clear up my confusion. Suppose the following:

class Base
{
protected:
int x;
};

class Derived : public Base
{
public:
void A( const Derived &d )
{ x = d.x; // Ok }
void B( const Base &b )
{ x = b.x; //Error: cannot access protected member declared in
class 'Base' }
};

What is the problem with B()?


I'm not sure, but you could have this structure:

class Base
{
protected:
int x;
};

class Dervied1 : public Base
{
};

class Dervied2: public Base
{
};

You could then pass an instance of Dervied2 as a 'Base' in to the
constructor of derived one, but they are off different hierachies, so
you'd have the case where Dervied1 was trying to access Dervied2::x
which I don't think is allowed so I think you can only access the
protected members of base if you have base as a Dervied1 type, i.e. same
type as you.

I've seen this (or something very similar with BCB6) so I assumed the
compiler was correct but I may be wrong on that.

Cheers

Russell

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

May 25 '06 #9
ol*******@sympatico.ca wrote:
Hi,

I am not sure if I have found a compiler bug (I am using VC++.NET2003)
or if this is the correct behavior defined by the language but I am
sure someone can clear up my confusion. Suppose the following:

class Base
{
protected:
int x;
};

class Derived : public Base
{
public:
void A( const Derived &d )
{ x = d.x; // Ok }
void B( const Base &b )
{ x = b.x; //Error: cannot access protected member declared in
class 'Base' }
};

What is the problem with B()? What should I change in Derived to fix
the problem? The best thing I came up is by modifying Base like this:
There is no problem, what you see is what you get. the parameter
references b, d are not part of the construct, its just a potential
object reference. Treat b, d as what they really are, an external
object. As you found out, the only way you can access x is through a
Derived object(access: protected).

Also, the use of Base::x only applies to this instance of the Derived
class. If you need a Derived object to provide read-access to its
protected x:

int Derived::getx() const
{
return Base:x;
}

The Base:: is not needed but it'll make the code readable.

class Base
{
protected:
void SetX(const Base &b) { x = b.x; }
int x;
};

and call SetX from B().


Look at void Derived::A(...), wouldn't you be better off with a copy
ctor that performs a deep copy? Interestingly enough, that would work
with x declared as having private access (hint).

Same goes with void Derived::B(...), you could write a conversion ctor
or provide an operator= or both that take a Base parameter.

Just because you have a daughter named Julie that has blond hair and the
neighbour also has a blond Julie doesn't mean the neighbour's daughter
also gets the key to the house. es cosa nostra.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

May 27 '06 #10

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

Similar topics

2
by: Jerry | last post by:
My "main" class is getting a bit long...Is it possble to split a class definition into several files and then import the pieces to get the whole definition? Jerry
6
by: Arthur J. O'Dwyer | last post by:
I was paging through Coplien's book "Advanced C++ Programming Styles and Idioms" this afternoon and found some code that looked something like void sort(vector<foo> a) { int flip; do { for...
166
by: Graham | last post by:
This has to do with class variables and instances variables. Given the following: <code> class _class: var = 0 #rest of the class
12
by: Sunny | last post by:
Hi All, I have a serious issue regarding classes scope and visibility. In my application, i have a class name "TextFile", and also a few other classes like "TotalWords", "TotalLines" and etc..,...
3
by: DDE | last post by:
Hi all, I have defined a meththod supposed to do some treatment with the class it receives as argument. This method can receive different type of classes so it's argument is defined as an...
1
by: rsheridan6 | last post by:
Hi, I'm writing a function to validate fields, and I'm confused about variable scope. Here's what I have: function RequiredField(name, error_message, error_display_id) { this.name = name;...
3
by: gyan | last post by:
Please go though following program: #include <iostream.h> class base { public: int basepublic; protected: int baseprotected; };
2
by: joe t. | last post by:
My apologies, i'm not sure how to ask this question correctly, so i'll give the examples as i go. First, i *think* my problem is described here, but i may be misunderstanding:...
2
by: JYA | last post by:
Hi. I was writing an xmltv parser using python when I faced some weirdness that I couldn't explain. What I'm doing, is read an xml file, create another dom object and copy the element from...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
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: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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
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?
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
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
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,...

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.