Covariant parameters

M

Marcin Vorbrodt

Can a base class have a virtual method that takes a base pointer/reference
as a parameter, and then overwrite this method in a derived class, and
change its parameter to be a reference/pointer to the derived type. Sort of
like covariance but on parameters rather than on return type.

Thanks,
Martin
 
W

White Wolf

Marcin said:
Can a base class have a virtual method that takes a base
pointer/reference as a parameter, and then overwrite this method in a
derived class, and change its parameter to be a reference/pointer to
the derived type. Sort of like covariance but on parameters rather
than on return type.

Nope. For two reasons: there are no methods in C++, especially virtual
ones. :) But there are member functions.

The virtual members functions can only differ in their return value. If
their signature differs then you will not get overriding, but you will
*hide* the virtual function of the base class.
 
G

Gabriel Schreiber

Marcin said:
Can a base class have a virtual method that takes a base pointer/reference
as a parameter, and then overwrite this method in a derived class, and
change its parameter to be a reference/pointer to the derived type. Sort of
like covariance but on parameters rather than on return type.

Thanks,
Martin

Hy Martin

No. (see other posting)

But: of cource a function(BaseClass* bc) can be called with a pointer to
derived class. I think this might actually solve your problem. (Of
cource, you must inherit public or call the function from inside the
class.)

A basic thing in polymorphism is, that pointers to objects can be
converted to pointers to public base classes.

Gabriel
 
T

tom_usenet

Can a base class have a virtual method that takes a base pointer/reference
as a parameter, and then overwrite this method in a derived class, and
change its parameter to be a reference/pointer to the derived type. Sort of
like covariance but on parameters rather than on return type.

This would break LSP. E.g.

baseptr->func(baseobjectptr);

If baseptr points to your derived object (where func expects a
derivedobjectptr), then what is meant to happen? A crash? An
exception? In any case, a runtime check is required.

So just take the exact parameter type from the base class to correctly
override the base method, and add the runtime check yourself. e.g.

void f(Base* ptr)
{
Derived* dp = dynamic_cast<Derived*>(dp);
if (dp == 0)
throw some_exception();

//use dp.
}

However, this is bad design since you are "cancelling" functionality
available in the base class and adding extra constraints to parameters
for derived classes.

Tom
 
A

Alf P. Steinbach

This would break LSP. E.g.

baseptr->func(baseobjectptr);

If baseptr points to your derived object (where func expects a
derivedobjectptr), then what is meant to happen? A crash? An
exception? In any case, a runtime check is required.

Allow me to expand a bit on that, because it's not the whole story.
Consider first why function results can be covariant. It is because
they are pure 'out' when regarded as parameters. Similarly, without
breaking the Liskov Substitution Principle, pure 'in' parameters can
in principle be contravariant. A parameter that is both 'in' and
'out' cannot be variant at all within the constraints of the LSP.

The problem is that C++ only partially supports the notion of 'in' and
'out'. Specifically, there's no way -- as far as I know -- to tell
the compiler that a parameter is strictly 'out'. Hence, from the C++
compiler's point of view a parameter that is intended as pure 'out'
appears as 'in'+'out', and so cannot be variant.

Ada does support 'in' and 'out' specifications, but strangely it seems it
wasn't considered when partial support for object-based programming was
added to that language (this problem area also seems to have been
overlooked in Ada's notion of initializers).

C# (but not Java) also supports 'in' and 'out', but again, strangely, that
isn't taken advantage of -- as far as I can read the specification.
 
T

tom_usenet

On Thu, 11 Sep 2003 11:59:57 GMT, (e-mail address removed) (Alf P. Steinbach)
wrot
Allow me to expand a bit on that, because it's not the whole story.
Consider first why function results can be covariant. It is because
they are pure 'out' when regarded as parameters. Similarly, without
breaking the Liskov Substitution Principle, pure 'in' parameters can
in principle be contravariant. A parameter that is both 'in' and
'out' cannot be variant at all within the constraints of the LSP.

I think that in general, covariance of out params is a lot more useful
than contravariance of in params (which is why we have the first, but
not the second). Do you know any realistic use cases for
contravariance?
The problem is that C++ only partially supports the notion of 'in' and
'out'. Specifically, there's no way -- as far as I know -- to tell
the compiler that a parameter is strictly 'out'. Hence, from the C++
compiler's point of view a parameter that is intended as pure 'out'
appears as 'in'+'out', and so cannot be variant.

The return type is pure "out" and by-value parameters are pure "in",
but I don't think that by-value parameters are really relevent, since
they couldn't be usefully contravariant.
Ada does support 'in' and 'out' specifications, but strangely it seems it
wasn't considered when partial support for object-based programming was
added to that language (this problem area also seems to have been
overlooked in Ada's notion of initializers).

C# (but not Java) also supports 'in' and 'out', but again, strangely, that
isn't taken advantage of -- as far as I can read the specification.

I remember being surprised at the lack of covariant returns in Java -
never used C# or Ada.

Tom
 
A

Alf P. Steinbach

On Thu, 11 Sep 2003 11:59:57 GMT, (e-mail address removed) (Alf P. Steinbach)
wrot

I think that in general, covariance of out params is a lot more useful
than contravariance of in params (which is why we have the first, but
not the second). Do you know any realistic use cases for
contravariance?

No. But it's part of the whole package, and as such I'm sure that
someone would find a use for it were it supported. More to the point
it's necessary to know about in order to understand things.


The return type is pure "out"

Yep, I noted that as the first thing in the posting you replied to.

and by-value parameters are pure "in",
but I don't think that by-value parameters are really relevent, since
they couldn't be usefully contravariant.

Ah, "couldn't be usefully contravariant"; that's very subjective...

It's nearly always the case that a simple, general mechanism is more
useful than a partial collection of individual special case mechanisms.

Never say never.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top