Connecting Tech Pros Worldwide Help | Site Map
 
 
LinkBack Thread Tools Search this Thread
  #1  
Old May 23rd, 2006, 12:25 PM
olanglois@sympatico.ca
Guest
 
Posts: n/a
Default 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! ]

  #2  
Old May 23rd, 2006, 01:45 PM
Victor Bazarov
Guest
 
Posts: n/a
Default Re: class acces scope weirdness

olanglois@sympatico.ca wrote:[color=blue]
> I am not sure if I have found a compiler bug (I am using VC++.NET2003)[/color]

No.
[color=blue]
> or if this is the correct behavior defined by the language[/color]

Yes.
[color=blue]
> 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' }[/color]

Correct behaviour.
[color=blue]
> };
>
> What is the problem with B()? What should I change in Derived to fix
> the problem?[/color]

Nothing. The derived class cannot access protected members in objects
of other than its own type.
[color=blue]
> 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().[/color]

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


  #3  
Old May 23rd, 2006, 09:55 PM
Jim Langston
Guest
 
Posts: n/a
Default Re: class acces scope weirdness


"Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
news:e4uvmj$np6$1@news.datemas.de...[color=blue]
> olanglois@sympatico.ca wrote:[color=green]
>> I am not sure if I have found a compiler bug (I am using VC++.NET2003)[/color]
>
> No.
>[color=green]
>> or if this is the correct behavior defined by the language[/color]
>
> Yes.
>[color=green]
>> 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' }[/color]
>
> Correct behaviour.
>[color=green]
>> };
>>
>> What is the problem with B()? What should I change in Derived to fix
>> the problem?[/color]
>
> Nothing. The derived class cannot access protected members in objects
> of other than its own type.[/color]

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.


  #4  
Old May 23rd, 2006, 10:05 PM
Victor Bazarov
Guest
 
Posts: n/a
Default Re: class acces scope weirdness

Jim Langston wrote:[color=blue]
> "Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
> news:e4uvmj$np6$1@news.datemas.de...[color=green]
>> olanglois@sympatico.ca wrote:[color=darkred]
>>> I am not sure if I have found a compiler bug (I am using
>>> VC++.NET2003)[/color]
>>
>> No.
>>[color=darkred]
>>> or if this is the correct behavior defined by the language[/color]
>>
>> Yes.
>>[color=darkred]
>>> 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' }[/color]
>>
>> Correct behaviour.
>>[color=darkred]
>>> };
>>>
>>> What is the problem with B()? What should I change in Derived to fix
>>> the problem?[/color]
>>
>> Nothing. The derived class cannot access protected members in
>> objects of other than its own type.[/color]
>
> 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?[/color]

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"?
[color=blue]
> 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.[/color]

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


  #5  
Old May 23rd, 2006, 10:55 PM
Mehturt@gmail.com
Guest
 
Posts: n/a
Default Re: class acces scope weirdness


olanglois@sympatico.ca wrote:[color=blue]
> 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
>[/color]

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! ]

  #6  
Old May 24th, 2006, 04:35 PM
Thomas Maeder
Guest
 
Posts: n/a
Default Re: class acces scope weirdness


olanglois@sympatico.ca wrote:[color=blue]
>
> 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:[/color]

The compiler is correct in this regard.

[color=blue]
> 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?[/color]

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! ]

  #7  
Old May 24th, 2006, 04:45 PM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: class acces scope weirdness

* olanglois@sympatico.ca:[color=blue]
> 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()?[/color]

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.

[color=blue]
> What should I change in Derived to fix the problem?[/color]

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! ]

  #8  
Old May 24th, 2006, 04:45 PM
cs2991@gmail.com
Guest
 
Posts: n/a
Default Re: class acces scope weirdness

> class Derived : public Base[color=blue]
> {
> 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:
>[/color]

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! ]

  #9  
Old May 25th, 2006, 09:15 PM
Russell Hind
Guest
 
Posts: n/a
Default Re: class acces scope weirdness

olanglois@sympatico.ca wrote:[color=blue]
> 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()?[/color]

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! ]

  #10  
Old May 27th, 2006, 11:55 AM
Salt_Peter
Guest
 
Posts: n/a
Default Re: class acces scope weirdness

olanglois@sympatico.ca wrote:[color=blue]
> 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:[/color]

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.
[color=blue]
>
> class Base
> {
> protected:
> void SetX(const Base &b) { x = b.x; }
> int x;
> };
>
> and call SetX from B().
>[/color]

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! ]

 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

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 205,338 network members.