我们不能在重新定义过程中修改虚函数的返回类型
如果返回一个指向基类的指针或引用,则该函数的重新定义版本将会从基类
返回的内容中返回一个指向派生类的指针或引用
//: C15:VariantReturn.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Returning a pointer or reference to a derived
// type during ovverriding
#include <iostream>
#include <string>
using namespace std;
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<Bird::BirdFood*>(b.eats());
getchar();
} ///:~
成员函数Pet::eats()返回一个指向PetFood的指针
在Bird中,完全按基类中的形式重载这个成员函数,并且包含了返回类型
但在Cat中,eats()的返回类型是指向CatFood的指针,而CatFood是派生于
PetFood的类
能返回确切的类型通用些,而且在自动地进行向上类型转换时不丢失特定的
信息
输出
Bird eats Bird food
Cat eats Birds