Thread View: comp.std.c++
2 messages
2 total messages
Started by Tom Ngo
Thu, 28 Mar 1991 14:36
Objects already contain type information => binary virtual functions
Author: Tom Ngo
Date: Thu, 28 Mar 1991 14:36
Date: Thu, 28 Mar 1991 14:36
75 lines
3011 bytes
3011 bytes
Here's a wild idea whose purpose is to permit typesafe downcasts under
certain circumstances. Do others think it's worth pursuing? Can it
be generalized?
The problem:
class B {
virtual void foo(B*);
};
class D : public B {
virtual void foo(D*);
};
void bar(B* b1, B* b2) {
b1.foo(b2);
}
D d1;
D d2;
bar(&d1,&d2); // I want D::foo to be invoked
Currently, D::foo does not override B::foo. A way to cause this
to happen is for D::foo to be declared D::foo(B*) and downcast B*
to D* within the body of D::foo. This downcast is considered
unsafe; see ARM p. 210-211.
I call foo() a "binary" virtual function, meaning that the
intention is for it to operate on two objects of identical type,
even if the call is made with references or pointers to a base
class of the type.
I feel there is a strong need for such functions, and that
currently there is no way to implement them that is both typesafe
and elegant. For example, if you have a container class designed
to take B*'s and you have given it all D*'s, the container class
ought to be able to do things like compare objects in a D-specific
manner, etc. Right now if you want to implement this sort of
thing in a typesafe manner you have to make two separate virtual
function calls, one for each operand of the comparison, or some
such thing.
The proposed solution:
It has been argued that to implement typesafe downcasts would
require that type information be added to each object. I suggest
that objects already contain type information in their virtual
function tables. So here's the idea:
1. Relax the requirement that two functions' arguments match
EXACTLY for one to override the other. Instead, permit
D::foo(D*) to match B::foo(B*).
(In general, any argument of type D* or D* in the argument
list of D::foo would match an argument of type B* or B* in
B::foo.)
2. In that case, in D::foo(D* that) the compiler should
automatically generate code that ensures:
this->foo == that->foo
(You know what I mean.) If the equality fails, then perhaps
an addressing exception should be generated.
This solution generalizes trivially to cases in which D::foo has
several D* arguments.
Comments?
--Tom
--
Tom Ngo
ngo@harvard.harvard.edu
617/495-1768 lab number, leave message
Re: Objects already contain type information => binary virtual functions
Author: Chip Salzenberg
Date: Sun, 31 Mar 1991 19:47
Date: Sun, 31 Mar 1991 19:47
33 lines
1560 bytes
1560 bytes
According to ngo@tammy.harvard.edu (Tom Ngo):
>The problem:
>
> class B {
> virtual void foo(B*);
> };
> class D : public B {
> virtual void foo(D*);
> };
>
> void bar(B* b1, B* b2) {
> b1.foo(b2);
> }
>
> D d1;
> D d2;
> bar(&d1,&d2); // I want D::foo to be invoked
To suppose that D::foo() should override B::foo() is to misunderstand
the meaning of virtual functions, namely:
A virtual function is _one_ function with potentially many
implementations.
The code quoted above shows that D::foo() is prepared to work on a D,
while B::foo() is prepared only for a B. Thus they are not the same
function. They may be equivalent in one way or another; they may even
have the same body. But they are not the _same_ function. So the use
of "virtual" for these two functions is a design error.
--
Chip Salzenberg at Teltronics/TCT <chip@tct.com>, <uunet!pdn!tct!chip>
"All this is conjecture of course, since I *only* post in the nude.
Nothing comes between me and my t.b. Nothing." -- Bill Coderre
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads