Topic: is (*x).y equivalent to x->y


Author: simonh@swidev.demon.co.uk (Simon Huntington)
Date: Thu, 24 Jun 1993 14:17:23 +0000
Raw View
In article <1993Jun22.121407.909@rcmcon.com> rmartin@rcmcon.com writes:

>However, what about (*a).f()
>
>The ARM says in 5.3 p.55
>
>     'The unary * operator means indirection: the expression
>     must be a pointer, and the result is an lvalue
>     referring to the object to which the expression points.
>     If the type of the expression is "pointer to T," the
>     type of the result is "T." '
>

Isn't the rule:

 virtual functions are always called using the virtual call mechanism?


The compiler can only optimize away virtual function calls, using direct
calls, where it is sure about which function wil be called. It just happens
that for: x.y, x is usually an object and so a virtual call is not required.


--
Simon Huntington




Author: rmartin@rcmcon.com (Robert Martin)
Date: Tue, 22 Jun 1993 12:14:07 GMT
Raw View
Virtual functions are dynamically bound when called through a pointer
or reference to the base class.

class A {public: virtual void f();}
class B : public A {public: virtual void f();}

main() {A*a = new B; a->f();} // calls B::f via dynamic binding.

However, what about (*a).f()

The ARM says in 5.3 p.55

     'The unary * operator means indirection: the expression
     must be a pointer, and the result is an lvalue
     referring to the object to which the expression points.
     If the type of the expression is "pointer to T," the
     type of the result is "T." '

This is a bit ambiguous.  the word "referring" might imply that unary
operator * returns a reference.  However the phrase: '...the type of the
result is "T" ' seems to imply that the expression *a returns a *value*
of type A, not a reference to type A.

When the dot operator is used with a *value* of type A to call virtual
function 'f', it should call A::f; since virtual functions are only
dynamically bound when called through a pointer or reference.  So what
should (*a).f() call?

It is no use to insist that s->m is always equivalent to (*s).m; since
the ability to overload the unary '*' and '->' operators makes hamburger
out of any intended equivalency.
--
Robert Martin       | Design Consulting   | Training courses offered:
R.C.M. Consulting   | rmartin@rcmcon.com  |   Object Oriented Analysis
2080 Cranbrook Rd.  | Tel: (708) 918-1004 |   Object Oriented Design
Green Oaks IL 60048 | Fax: (708) 918-1023 |   C++




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Tue, 22 Jun 1993 16:12:35 GMT
Raw View
In article <1993Jun22.121407.909@rcmcon.com> rmartin@rcmcon.com (Robert Martin) writes:
>Virtual functions are dynamically bound when called through a pointer
>or reference to the base class.
>
>class A {public: virtual void f();}
>class B : public A {public: virtual void f();}
>
>main() {A*a = new B; a->f();} // calls B::f via dynamic binding.
>
>However, what about (*a).f()
>
>The ARM says in 5.3 p.55
>
>     'The unary * operator means indirection: the expression
>     must be a pointer, and the result is an lvalue
>     referring to the object to which the expression points.
>     If the type of the expression is "pointer to T," the
>     type of the result is "T." '
>
>This is a bit ambiguous.  the word "referring" might imply that unary
>operator * returns a reference.  However the phrase: '...the type of the
>result is "T" ' seems to imply that the expression *a returns a *value*
>of type A, not a reference to type A.

 Its a bit messy: IMHO the distinction is categorically
invalid. (In the wrong category).

>When the dot operator is used with a *value* of type A to call virtual
>function 'f', it should call A::f; since virtual functions are only
>dynamically bound when called through a pointer or reference.  So what
>should (*a).f() call?

 Same as

 a->f();

that is, its a virtual call unless a copy is made. *a does not
create a copy: its an lvalue and refers to the object whose address
was in 'a'. (Even though the ARM may not say this, I'm sure
that is intended :-)

>
>It is no use to insist that s->m is always equivalent to (*s).m; since
>the ability to overload the unary '*' and '->' operators makes hamburger
>out of any intended equivalency.

 operator* applied to a pointer cannot be overloaded.
 neither can operator-> for a pointer

 Therefore, if 'a' is a pointer:

 (*a).f();
 a->f();

are equivalent, as in C. This is not true if 'a' is a class object,
where both -> and * can be overloaded (but . cant :-(

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Tue, 22 Jun 1993 20:17:55 GMT
Raw View
In article <1993Jun22.121407.909@rcmcon.com> rmartin@rcmcon.com (Robert Martin) writes:
>Virtual functions are dynamically bound when called through a pointer
>
>This is a bit ambiguous.  the word "referring" might imply that unary
>operator * returns a reference.  However the phrase: '...the type of the
>result is "T" ' seems to imply that the expression *a returns a *value*
>of type A, not a reference to type A.

That's right.  Have you ever heard of an lvalue?

For all practical purposes, and lvalue of type T *is* a reference to an
object of type T and vise versa.

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: dlarsson@aut.abb.se (Daniel Larsson)
Date: Tue, 22 Jun 1993 17:24:39 GMT
Raw View
In article <1993Jun22.121407.909@rcmcon.com> rmartin@rcmcon.com (Robert Martin) writes:
> ...
>
>The ARM says in 5.3 p.55
>
>     'The unary * operator means indirection: the expression
>     must be a pointer, and the result is an lvalue
>     referring to the object to which the expression points.
>     If the type of the expression is "pointer to T," the
>     type of the result is "T." '
>
>This is a bit ambiguous.  the word "referring" might imply that unary
>operator * returns a reference.  However the phrase: '...the type of the
>result is "T" ' seems to imply that the expression *a returns a *value*
>of type A, not a reference to type A.
>
>When the dot operator is used with a *value* of type A to call virtual
>function 'f', it should call A::f; since virtual functions are only
>dynamically bound when called through a pointer or reference.  So what
>should (*a).f() call?
>

Well, without really knowing, I'm pretty sure the call should be virtual. As
the ARM is saying, the result of applying the standard unary * is a lvalue,
the result can hardly be a *value* of T, but rather a *reference* to T despite
what it says later.


--
Daniel Larsson          Email:    dlarsson@aut.abb.se
ABB Automation AB Telefax:   +46 21 34 25 55
S-721 67 Vaesteraas Telephone: +46 21 34 30 29