 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Liysh Guest
|
Posted: Sat Nov 26, 2005 2:27 pm Post subject: Variant return type |
|
|
According to Thinking in C++
"You cannot modify the return type of a virtual function during
overriding.but there is a special case in which you can slightly
modify the return type. If you=A1=AFre returning a pointer or a
reference to a base class, then the overridden version of the function
may return a pointer or reference to a class derived from what the base
returns." And here's the example:
class PetFood
{
public:
virtual string foodType() const = 0;
};
class Pet
{
public:
virtual string type() const = 0;
virtual PetFood* eats() = 0;
};
class Bird : public Pet
{
public:
string type() const { return "Bird"; }
class BirdFood : public PetFood
{
public:
string foodType() const
{
return "Bird food";
}
};
// Upcast to base type:
PetFood* eats() { return &bf; }
private:
BirdFood bf;
};
class Cat : public Pet
{
public:
string type() const { return "Cat"; }
class CatFood : public PetFood
{
public:
string foodType() const { return "Birds"; }
};
// Return exact type instead:
CatFood* eats() { return &cf; }
private:
CatFood cf;
};
int main()
{
Bird b;
Cat c;
Pet* p[] { &b, &c, };
for(int i = 0; i < sizeof p / sizeof *p; i++)
cout << p[i]->type() << " eats "
<< p[i]->eats()->foodType() << endl;
// Can return the exact type:
Cat::CatFood* cf = c.eats();
Bird::BirdFood* bf;
// Cannot return the exact type:
//! bf = b.eats();
// Must downcast:
bf = dynamic_cast
}
What annoying me is that once I get code above compiled, I get a
compiler error saying
"overriding virtual function differs from 'Pet::eats' only by return
type or calling convention" which is for "CatFood* eats() { return &cf;}"
But this differ is author's intension, How's that was flagged as an
error?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Bob Hairgrove Guest
|
Posted: Sat Nov 26, 2005 9:42 pm Post subject: Re: Variant return type |
|
|
On 26 Nov 2005 09:27:38 -0500, "Liysh" <liysh (AT) intertimes (DOT) com.cn>
wrote:
| Quote: | According to Thinking in C++
"You cannot modify the return type of a virtual function during
overriding.but there is a special case in which you can slightly
modify the return type. If you=A1=AFre returning a pointer or a
reference to a base class, then the overridden version of the function
may return a pointer or reference to a class derived from what the base
returns."
|
That's known as "covariant return type".
| Quote: | And here's the example:
|
(Note: you should add a virtual destructor to your base classes if you
ever need to delete an instance of the derived class through a base
class pointer. It might not be necessary here, but it's always a good
idea.)
| Quote: | class PetFood
{
public:
virtual string foodType() const = 0;
};
class Pet
{
public:
virtual string type() const = 0;
virtual PetFood* eats() = 0;
};
class Bird : public Pet
{
public:
string type() const { return "Bird"; }
class BirdFood : public PetFood
{
public:
string foodType() const
{
return "Bird food";
}
};
// Upcast to base type:
PetFood* eats() { return &bf; }
private:
BirdFood bf;
};
|
Since BirdFood derives from PetFood, you could return a BirdFood*
here.
| Quote: | class Cat : public Pet
{
public:
string type() const { return "Cat"; }
class CatFood : public PetFood
{
public:
string foodType() const { return "Birds"; }
};
// Return exact type instead:
CatFood* eats() { return &cf; }
private:
CatFood cf;
};
int main()
{
Bird b;
Cat c;
Pet* p[] { &b, &c, };
for(int i = 0; i < sizeof p / sizeof *p; i++)
cout << p[i]->type() << " eats "
p[i]->eats()->foodType() << endl;
// Can return the exact type:
Cat::CatFood* cf = c.eats();
Bird::BirdFood* bf;
// Cannot return the exact type:
//! bf = b.eats();
// Must downcast:
bf = dynamic_cast
|
That's because you return a PetFood* from Bird::eats() instead of a
Bird::BirdFood*.
| Quote: | }
What annoying me is that once I get code above compiled, I get a
compiler error saying
"overriding virtual function differs from 'Pet::eats' only by return
type or calling convention" which is for "CatFood* eats() { return &cf;}"
But this differ is author's intension, How's that was flagged as an
error?
|
Does it compile if you change the return type of Bird::eats()? If not,
you might need to get a newer compiler that supports covariant return
types.
--
Bob Hairgrove
[email]NoSpamPlease (AT) Home (DOT) com[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alberto Ganesh Barbati Guest
|
Posted: Sun Nov 27, 2005 5:56 pm Post subject: Covariant return type (was Re: Variant return type) |
|
|
Liysh wrote:
| Quote: |
What annoying me is that once I get code above compiled, I get a
compiler error saying
"overriding virtual function differs from 'Pet::eats' only by return
type or calling convention" which is for "CatFood* eats() { return &cf;}"
But this differ is author's intension, How's that was flagged as an
error?
|
The code is ok, except for a missing "=" in line "Pet* p[] { &b, &c, };"
probably stripped due to "quoted-printable" madness. It should compile
on a conformant compiler. You didn't mention which compiler you are
using so I am inclined to think it is probably outdated or buggy. It is
well known that compilers have implemented this feature only very recently.
Ganesh
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|