Topic: different return types for virtual functions
Author: mwoolf@cix.compulink.co.uk ("Matthew Woolf")
Date: Fri, 23 Dec 1994 23:50:15 GMT Raw View
I suppose the thought behind this is the generic "Get at my superclass"
version of this - a way of identifying the object as declared rather than
as used. Let me make myself clearer...
struct aType { virtual aType *declared() { return this ; } } ;
struct bType { virtual bType *declared() { return this ; } } ;
struct miType:public aType,public bType
{
virtual miType *declared() { return this ; }
void Wow() { cout << "Wow" ; }
} ;
I can declare "miType p = new miType" and pass 'p' to any function
expecting aType* or bType* without error - the compiler implicitly
"knows" how to convert to a pointer of either base type (the same in the
above example 'cos there are no data memebers!).
My problem is that what I want to say inside one of these functions is:
void f(bType *p)
{
p->declared()->Wow() ;
}
Since p->declared() virtualises to miType::declared() I should be able to
call member functions of miType, right? But what if 'p' was _really_ a
bType*, the ->Wow() is obviously nonsense. So am I back to type casts?
If all this sounds silly, I can explain why I want to do the above - it's
a type safe version of the old void* stuff.
Comments, explanations most welcome!
Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 23 Dec 1994 00:27:25 GMT Raw View
davidm@rational.com (David Moore) writes:
>kuhlins@hawk.wifo.uni-mannheim.de (Stefan Kuhlins) writes:
>>Now one can override a virtual member function with a different
>>return type:
>>struct B {
>> virtual B* clone() const { return new B(*this); }
>>};
>>struct A : B {
>> A* clone() const { return new A(*this); }
>>};
>Was this a recent change? I know the compiler I am using
>won't allow this (but it might just be broke)
Yes, and few compilers support it yet.
--
Steve Clamage, stephen.clamage@eng.sun.com
Author: kkp@prodax.fi (Keijo Pulkkinen)
Date: 23 Dec 1994 13:15:00 GMT Raw View
In article <3dd5hd$ovj@engnews2.Eng.Sun.COM>, clamage@Eng.Sun.COM (Steve Clamage) says:
>
>davidm@rational.com (David Moore) writes:
>
>>kuhlins@hawk.wifo.uni-mannheim.de (Stefan Kuhlins) writes:
>
>
>>>Now one can override a virtual member function with a different
>>>return type:
>
>>>struct B {
>>> virtual B* clone() const { return new B(*this); }
>>>};
>
>>>struct A : B {
>>> A* clone() const { return new A(*this); }
>>>};
>
>
>>Was this a recent change? I know the compiler I am using
>>won't allow this (but it might just be broke)
>
>Yes, and few compilers support it yet.
>
>--
>Steve Clamage, stephen.clamage@eng.sun.com
Hey, this is cool.
Which compilers do you that support this already?
When did this get included in Ansi draft?
-------------------o00O------O00o---
Keijo Pulkkinen,
Prodax-Logix, Finland
kkp@prodax.fi
Author: davidm@rational.com (David Moore)
Date: 22 Dec 1994 19:58:03 GMT Raw View
kuhlins@hawk.wifo.uni-mannheim.de (Stefan Kuhlins) writes:
>Now one can override a virtual member function with a different
>return type:
>struct B {
> virtual B* clone() const { return new B(*this); }
>};
>struct A : B {
> A* clone() const { return new A(*this); }
>};
>Do you know a good example for this "feature"?
>Or the reasons behind this feature?
>Thanks for your time,
> Stefan
Was this a recent change? I know the compiler I am using
won't allow this (but it might just be broke)
One often wants to derive a class and instead of
class A {
public:
A* foo();
}
in B, you want to declare that foo returns objects that
are knwon to be of type B.
class B : public A {
public:
B* foo();
}
Otherwise you have to cast, which is dangerous (or was
until safe casts were introduced). I know I have
fallen into this particular pit - casting
something wrongly, so this new form is greatly preferrable.
Author: swf@elsegundoca.ncr.com (Stan Friesen)
Date: Tue, 20 Dec 1994 17:35:05 GMT Raw View
In article <KUHLINS.94Dec16085129@hawk.wifo.uni-mannheim.de>, kuhlins@hawk.wifo.uni-mannheim.de (Stefan Kuhlins) writes:
|>
|> Now one can override a virtual member function with a different
|> return type:
|>
|> struct B {
|> virtual B* clone() const { return new B(*this); }
|> };
|>
|> struct A : B {
|> A* clone() const { return new A(*this); }
|> };
|>
|> Do you know a good example for this "feature"?
This is called return type covariance, and you have started a good example.
|> Or the reasons behind this feature?
|>
To show why it is useful, let's continue your example.
Suppose one has a variable:
A first_a;
now, I want to clone this A.
WITHOUT covariance, I would have to do this:
A *ap = (A *)first_a.clone();
WITH covariance, I can do the following:
A *ap = first_a.clone();
Now, since type casts bypass the type system, and introduce a real
potential for error, this latter form is much safer, and more obviously
correct.
--
swf@elsegundoca.attgis.com sarima@netcom.com
The peace of God be with you.
Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 18 Dec 1994 01:48:36 GMT Raw View
kuhlins@hawk.wifo.uni-mannheim.de (Stefan Kuhlins) writes:
>Now one can override a virtual member function with a different
>return type:
>struct B {
> virtual B* clone() const { return new B(*this); }
>};
>struct A : B {
> A* clone() const { return new A(*this); }
>};
>Do you know a good example for this "feature"?
>Or the reasons behind this feature?
You answered your own question. Code like the above is the reason
for changing the language to allow covariant return types. The
alternative is to require casts everywhere.
--
Steve Clamage, stephen.clamage@eng.sun.com
Author: kuhlins@hawk.wifo.uni-mannheim.de (Stefan Kuhlins)
Date: 16 Dec 1994 07:51:29 GMT Raw View
Now one can override a virtual member function with a different
return type:
struct B {
virtual B* clone() const { return new B(*this); }
};
struct A : B {
A* clone() const { return new A(*this); }
};
Do you know a good example for this "feature"?
Or the reasons behind this feature?
Thanks for your time,
Stefan
Author: huber@kazoo.cs.uiuc.edu (Jay Huber)
Date: 16 Dec 1994 18:46:50 GMT Raw View
In article <KUHLINS.94Dec16085129@hawk.wifo.uni-mannheim.de>, kuhlins@hawk.wifo.uni-mannheim.de (Stefan Kuhlins) writes:
|>
|> Now one can override a virtual member function with a different
|> return type:
|>
|> struct B {
|> virtual B* clone() const { return new B(*this); }
|> };
|>
|> struct A : B {
|> A* clone() const { return new A(*this); }
|> };
|>
|> Do you know a good example for this "feature"?
|> Or the reasons behind this feature?
|>
|> Thanks for your time,
|> Stefan
|>
Well, for one thing it is necessary when you have MI:
class B1 {
public:
virtual B1 * clone() const { return new B1(*this); }
virtual ~B1() {}
};
class B2 {
public:
virtual B2 * clone() const { return new B2(*this); }
virtual ~B2() {}
};
class Foo : public B1, public B2 {
public:
virtual Foo * clone() const { return new Foo(*this); }
virtual ~Foo() {}
};
but according to D&E, the reason it was adopted was that it allowed
one to eliminate a very common need for typecasts.