我有这组课程。
class Animal {
public:
Animal(uint32_t attr1, uint32_t attr2);
virtual uint32_t get_attr1() const;
virtual uint32_t get_attr2() const;
private:
uint32_t attr1;
uint32_t attr2;
};
class Dog: public Animal {
public:
Dog(uint32_t attr1, uint32_t attr2, uint32_t attr3);
uint32_t get_attr3() const;
private:
uint32_t attr3;
};
class Cat: public Animal {
public:
Cat(uint32_t attr1, uint32_t attr2, uint32_t attr4);
uint32_t get_attr4() const;
private:
uint32_t attr4;
};
现在我想拥有
vector<Animal*> animals;
以及一些声明如下的函数:
void f(Dog* dog);
void f(Cat* cat);
和这个代码:
for (auto animal: animals) {
f(animal);
}
如何利用这段代码实现多态?看起来动物不像猫或狗那样被对待。
制作一个f()
将 aAnimal*
作为输入的重载,然后您的for
循环将按照您编写的方式工作。然后f()
为Dog
and调用单独的重载Cat
,您必须dynamic_cast
在运行时使用,例如:
void f(Dog* dog)
{
// do something only a dog can do ...
}
void f(Cat* cat)
{
// do something only a cat can do ...
}
void f(Animal *animal)
{
if (Dog *dog = dynamic_cast<Dog*>(animal)) {
f(dog);
}
else if (Cat *cat = dynamic_cast<Cat*>(animal)) {
f(cat);
}
}
...
for (auto animal: animals) {
f(animal);
}
然而,这违背了多态性的原则。如果f()
需要根据Animal
调用的类型做不同的事情,应该是类的虚方法Animal
,然后后代可以根据需要覆盖它:
class Animal {
public:
...
virtual ~Animal() {} // <-- don't forget this!
...
virtual void f() = 0;
};
class Dog: public Animal {
public:
...
void f() override;
};
class Cat: public Animal {
public:
...
void f() override;
};
void Dog::f()
{
// do something only a dog can do ...
}
void Cat::f()
{
// do something only a cat can do ...
}
...
for (auto animal: animals) {
animal->f();
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句