wkd@asc.slb.com (Bill Duttweiler) (03/15/91)
Is it illegal to call a protected member function on an instance other than 'this'? Consider the following simple example: class A { public: A(); protected: void SetState(); }; class B : public A { public: B(A* a) { MyA = a; } void Foo() { MyA->SetState(); } protected: A *MyA; }; When run through g++ (1.37.1), I get the following error message: test.cc: In method void B::Foo (): test.cc:13: method `void A::SetState ()' is protected When run through Sun C++ (based on cfront 2.0), I get "test.cc", line 13: error: B::Foo() cannot access A::SetState(): protected member So, these compilers agree. But I don't: B is publicly derived from A and should have access to protected member functions from within its own member functions. I can call SetState() on 'this', why not on MyA??? -- William K. Duttweiler Schlumberger Austin Systems Center (512) 331-3000 PO Box 200015 wkd@asc.slb.com Austin, TX 78720-0015
mittle@blinn.watson.ibm.com (Josh Mittleman) (03/16/91)
ARM, p.253, reads "A friend or member function of a derived class can
access a protected nonstatic member of base of its base classes only
through a pointer to, reference to, or object of the derived class (or any
class derived from that class)." A discussion of this restriction can be
found on pp.254-5.
A::SetState() is a protected member of A and, by virtue of the public
derivation, B::SetState() is a protected member of B. But they aren't the
same thing, although they have the same implementation. Member functions
of B can access B::SetState(), but they have no access to the protected
parts of an A object; only members and friends of A can access those.
Given your original code, suppose there were some other class C : public A,
in which SetState() were overloaded:
class C : public A
{
protected: void SetState();
};
Now, we do this:
C objectC;
B objectB(&C); // C is a A, so the C* is automatically converted to A*.
B.Foo(); // wrong: invokes C->A::SetState() instead of
// C->C::SetState().
Of course, this error could be avoided by making SetState() virtual, but it
still is an incorrect result.
===========================================================================
Josh Mittleman (mittle@ibm.com or joshua@paul.rutgers.edu)
J2-C28 T.J. Watson Research Center, PO Box 704, Yorktown Heights, NY 10598
dsouza@gwen.cad.mcc.com (Desmond Dsouza) (03/16/91)
wkd@asc.slb.com (Bill Duttweiler) asks: >Is it illegal to call a protected member function on an instance other >than 'this'? Consider the following simple example: The derived class has access to inherited protected data members within the context of ANY object OF ITS CLASS, not just "this" (also of further derived classes). See ARM, p. 253 class A { protected: int i; }; class B : public A { public: foo (B* bp, A* ap) { bp->i = 5; // OK ap->i = 5; // ERROR: } }; -- Desmond. -- ------------------------------------------------------------------------------- Desmond D'Souza, MCC CAD Program | ARPA: dsouza@mcc.com | Phone: [512] 338-3324 Box 200195, Austin, TX 78720 | UUCP: {uunet,harvard,gatech,pyramid}!cs.utexas.edu!milano!cadillac!dsouza
mwb@ulysses.att.com (Michael W. Balk) (03/17/91)
In article <1991Mar14.215717.28199@asc.slb.com>, wkd@asc.slb.com (Bill Duttweiler) writes: > > Is it illegal to call a protected member function on an instance other > than 'this'? Consider the following simple example: > > class A > { > public: > A(); > protected: > void SetState(); > }; > > class B : public A > { > public: > B(A* a) { MyA = a; } > void Foo() { MyA->SetState(); } > protected: > A *MyA; > }; The problem here is that MyA is a pointer to an instance of A -- it is *not* an instance of B. In otherwords, MyA->SetState() is not permitted regardless of whether Foo is a member function of class B or not. If this were not the case, then one could access the protected and private members of any object simply by deriving from that object's class. In order to access A::SetState from an instance of class B, class B should be modified as follows: class B : public A { public: B() {} void Foo() { SetState(); } }; Since B is derived from A it already contains everything that is in A through the derivation. In the above definition of class B, Foo executes a member function of the base part of the same object. This is legal since and instance of B is also an A. Michael W. Balk AT&T Bell Laboratories Murray Hill, NJ 07974 mwb@ulysses.att.com