Article View: comp.std.c++
Article #989Objects already contain type information => binary virtual functions
From: 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
Technical Details
Message-ID:
<NGO.91Mar28093648@tammy.harvard.edu>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!snorkelwacker.mit.edu!hsdndev!husc6!ngoShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!snorkelwacker.mit.edu!hsdndev!husc6!ngo From: ngo@tammy.harvard.edu (Tom Ngo) Newsgroups: comp.std.c++ Subject: Objects already contain type information => binary virtual functions Message-ID: <NGO.91Mar28093648@tammy.harvard.edu> Date: 28 Mar 91 14:36:48 GMT Sender: news@husc6.harvard.edu Distribution: comp Organization: Harvard Chemistry Department Lines: 75