假设我们有一个班级git status
和一个班级Mammal
。 Dog
通过代码Dog
从Mammal
继承了部分成员。
现在,在我正在阅读的书中,它使用代码class Dog : public Mammal {};
初始化main中的指针。我问的问题是,为什么Mammal *pDog = new Dog
指针用于指向堆中的Mammal
?
代码Dog
不会更有意义且更具可读性吗?或者使用前代码有什么好处?
答案 0 :(得分:0)
或者使用以前的代码是否有优势?
当然,客户端代码并不需要知道Mammal
实际上是Dog
还是Giraffe
。它被称为多态。
两者都可以使用完全不同的实现来提供pee();
和poop();
等功能:
class Mammal {
public:
virtual void pee() = 0;
virtual void poop() = 0;
virtual ~Mammal() {}
};
class Dog : public Mammal {
public:
virtual void pee() {
// Doggy style
}
virtual void poop() {
// Doggy style
}
};
class Giraffe : public Mammal {
public:
virtual void pee() {
// Giraffe style
}
virtual void poop() {
// Giraffe style
}
};
客户端函数可能只需要Mammal
指针或引用,而不知道实际传递了哪种Mammal
:
void doTheInevitable(Mammal* m) {
m->pee();
m->poop();
}
Dog dog;
Giraffe giraffe;
doTheInevitable(&dog);
doTheInevitable(&giraffe);
但具体实施仍然适用。
答案 1 :(得分:0)
如果您正在编写仅用于与狗一起工作的代码,那么您将使用Dog *pDog = new Dog;
。但是如果你有一个适用于任何类型哺乳动物的更通用的应用程序,你可以编写Mammap *pDog = new Dog;
,然后将该指针传递给泛型函数。然后它可以调用Mammal
基类中声明的成员函数,但如果Dog
覆盖它们,它将获得特定于Dog的行为。
这是多态性的本质。它允许您编写通用函数,然后将它们与更具体类型的实例一起使用。