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.