[comp.lang.c++] proposed info-hiding mechanism

mikem@otc.UUCP (03/12/87)

In article <408@inria.UUCP>, shapiro@inria.UUCP (Marc Shapiro) writes:
> 
> [ ... deleted ... ]
> 
>   class sosObject {
> 	long size;
> 	int fd;
>    protected:
> 	write_me_to_disk () {return ::write(fd, (void*)this, size);}
> 	}
> 
>   class A: public sosObject {
> 	...
> 	}
> 
>   class B: public sosObject {
> 	foo (A *a) { a -> write_me_to_disk(); }		// legal !
> 	}
> 
> The above example shows that even though B is not derived from A, B has
> access to A's 'protected' members.
> 

Surely this is simply just a BUG, and is not really legal at all. My
understanding was that things derived from A would be able to access
A's write_me_to_disk(), but certainly this would be prohibited for
siblings of A.

There is at least one other bug in release 1.1 which I'm aware of that
relates to this sort of thing:

    class Base {
	protected:
	    prot_member();
    };

    class Derived : public Base {
	 // Derived can use prot_member()

	 friend somefunc(Derived *d) { d->prot_member(); }

			      // somefunc should be able to use prot_member()
			      // for an object of type Derived. In release
			      // 1.1 this gives an error message complaining
			      // that prot_member is protected.
    };


I suspect that release 1.2 may address this, but since we're currently
awaiting delivery, I can't say for sure. I might post a follow-up when
we have 1.2 going.

			Mike Mowbray
			Systems Development
			Overseas Telecommunications Commission (Australia)

UUCP:   {seismo,mcvax}!otc.oz!mikem              ACSnet: mikem@otc.oz

bs@alice.UUCP (03/31/87)

shapiro@inria.UUCP (Marc Shapiro) writes:

 >   class sosObject {
 > 	long size;
 > 	int fd;
 >    protected:
 > 	write_me_to_disk () {return ::write(fd, (void*)this, size);}
 > 	}
 > 
 >   class A: public sosObject {
 > 	...
 > 	}
 > 
 >   class B: public sosObject {
 > 	foo (A *a) { a -> write_me_to_disk(); }		// legal !
 > 	}
 > 
 > The above example shows that even though B is not derived from A, B has
 > access to A's 'protected' members.

Correct. The unit of protection in C++ is a class; not an individual object.
There are cases where the class is the ideal unit of protection and cases
where the object is. Concievably an ideal language would give the programmer
a choice.

mikem@otc.UUCP (Mike Mobray) writes:

 >    class Base {
 >	protected:
 >	    prot_member();
 >    };
 >
 >    class Derived : public Base {
 >	 // Derived can use prot_member()
 >
 >	 friend somefunc(Derived *d) { d->prot_member(); }
 >
 >			      // somefunc should be able to use prot_member()
 >			      // for an object of type Derived. In release
 >			      // 1.1 this gives an error message complaining
 >			      // that prot_member is protected.
 >   };

Again, cfront is correct. A friend does not have access to protected members
of a base class of the class it is a friend of. A protected member is accessible
by members of a derived class and by friends of its class. In the example
above somefunc() is neither a member of Derived nor a friend of Base.

One might conceiveably use the less restrictive rule that ``a friend can
access anything a member can'', but the implications of such a relaxation
of the rules are not obvious and quite nasty to implement.