By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,550 Members | 1,733 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,550 IT Pros & Developers. It's quick & easy.

class acces scope weirdness

P: n/a
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
Share this Question
Share on Google+
9 Replies


P: n/a
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

P: n/a

"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

P: n/a
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

P: n/a

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

P: n/a

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

P: n/a
* 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

P: n/a
> 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

P: n/a
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

P: n/a
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 discussion thread is closed

Replies have been disabled for this discussion.