C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

accessing base members

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Luke
Guest





PostPosted: Thu Aug 03, 2006 7:56 am    Post subject: accessing base members Reply with quote



Hi all,

In C++ you can access a private member in a different object of the same
type in a member function. So:

class A {
public:
A () : x (0) {}
A (const A& a) : x (a.x) {} // <-- accessing private x in a
private:
int x;
};

But I cannot access a protected member in a different object of a base
type. So:

class A {
protected:
int x;
};

class B : public A {
public:
void f (A& a) { a.x = 0; } // <-- error: cannot acces protected
// member A:Mad
};

To me, that's very unlogical! I see no reason why this is wrong:
- Type safety is type-based, so I would expect that any member
function of type B can access any protected member of any
object of a base type of B. Basically the same behaviour as if
both object are of the same type (first example).
- The compiler has all needed information available, because
you cannot derive from a partial type.

It does work with static members however:

class A {
protected:
int x;
static void set_x (A& a, int xx) { a.x = xx; }
};

class B : public A {
public:
void f (A& a) { set_x (a, 0); } // <-- ok
};

I tested it with VC6, VC8, gcc 3.4 and gcc 4, all issue the same error.
So what am I'm missing? Is it by design, or is it a bug? And if it is by
design, what's the logic behind it?

Thanks, Luke

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





PostPosted: Fri Aug 04, 2006 12:07 am    Post subject: Re: accessing base members Reply with quote



Quote:
In C++ you can access a private member in a different object of the same
type in a member function.

Yes.

Quote:
But I cannot access a protected member in a different object of a base
type.

Yes, exactly.

Quote:
To me, that's very unlogical! I see no reason why this is wrong:

A derived class can access the protected interface of its base class.
If it could access the protected interface of ANY object using the same
base class, it would expose data to unrelated objects.

For a contrived example, this code shows why it is NOT a good idea to
do what you are wishing. It is a re-enactment of Watergate, C++ style:

#include "secret.hpp"
#include <iostream>

class headquarters
{
protected:
secret_files keep_out_;
};

class democrat_hq : public headquarters { /*...*/ };

class republican_hq : public headquarters
{
public:
void snoop(headquarters const & hq)
{
std::cout << hq.keep_out_ << std::endl;
}
};

int main()
{
democrat_hq dhq;
republican_hq rhq;
rhq.snoop(dhq); // UH OH!
}

Fortunately, it doesn't compile. For snoop() to work, it would have to
take a reference to a republican_hq as its argument. But then you
would not be able to pass in a democrat_hq. (Though the current
administration would probably just use a reinterpret_cast to get around
that!)

The only time an object can access the protected members of another
object's base class is if the other object is the same type (or
inherits from the same type) as itself. If it is passed in as a base,
then the type system cannot be sure that the underlying object is the
right type, and so access is denied.

--
Chris


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





PostPosted: Fri Aug 04, 2006 2:47 am    Post subject: Re: accessing base members Reply with quote



In article <1154588769.708944.298130 (AT) m73g2000cwd (DOT) googlegroups.com>,
"Thomas" <thomas (AT) tansasystems (DOT) com> wrote:

Quote:
You could say that a class always is declared as a friend of itself.

Isn't friendship a type relation, and not an object relation? This
implies that every instance is in fact of a different type, or, that
there are two kinds of friendship: type-friendship and
instance-friendship.

Quote:
And friendship is not inherited in C++, not in the real world ether Smile
. That's why your code above doesn't compile. The reason for this
"compiler generated friend class of itself", I guess, is that if the
copy constructor (or asignment operator) should do its job, then it
have to have access to the data of the object it will copy from. If it
didn't, you had to make access functions to all data if you wanted a
copy constructor, and what should the compiler generated copy
constructor do? So for me, to have every class to be friend of itself,
is logical.

But why is not friendship inherited? if so what would be the point of
having protected members? Protected members should only be accessed by
objects of the derived class or objects of the class declaring the
member. If every class was friend with inherited classes then the
private member would act protected to the derived class but private to
the outside world. You would never have real private members.

I agree that this would destroy encapsulation.
But inheriting friendship is not needed for this.
- The compiler knows we are in the context of a member function.
- The compiler knows we're accessing an object as a base type.
- It already works this way for privates and statics.
Quote:

It does work with static members however:

class A {
protected:
int x;
static void set_x (A& a, int xx) { a.x = xx; }
};

class B : public A {
public:
void f (A& a) { set_x (a, 0); } // <-- ok
};


set_x(..) is protected in A, so B should inherit this function, and
here you call set_x(..) class B. So this should be OK. The logic is of
couars, that if set_x is protected, all derived class can accsess this
functin by calline set_x(..) :)


Why is the same not true for a non-static member function? That is, if
I declare set_x as non-static member in A, I cannot call it on an
instance other then 'this':

void B::f(A& a) { set_x (a, 0); } // <-- ok
void B::f(A& a) { a.set_x (0); } // <-- error

I'm trying to think of an example where allowing access on protected
members in a member function via a pointer that is not 'this' causes
havoc (break encapsulation), but I can't think of any.

Quote:
I know my explanations is not allways perfect, but I hope this helps.

-Thomas


Maybe I should rephrase my question: why is 'this' special?

In the sense that in a member function of a type derived from T, I can
only access protected base members via 'this', but not via any other
pointer T. Is this the same in all OO languages? And is there a deep
reason for it, or is it just 'convenience' for compiler builders.

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





PostPosted: Thu Aug 17, 2006 3:24 am    Post subject: Re: accessing base members Reply with quote

Luke wrote:
Quote:
Hi all,

In C++ you can access a private member in a different object of the same
type in a member function. So:

[...]

But I cannot access a protected member in a different object of a base
type.

To my mind, this is for very pragmatic reasons: one class is one unit
of responsibility. The programmer who wrote or who is maintaining the
class can mess up with the class internals, it's her duty to get it
right; the programmer responsible of any derived class is just not
allowed to do this, in order to not mess up the work done by the first
programmer.

Cheers
Paavo


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.