C++ C++;简单示例中的多态性

C++ C++;简单示例中的多态性,c++,c++11,polymorphism,C++,C++11,Polymorphism,我有这套课程 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: Do

我有这套课程

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;
该代码:

for (auto animal: animals) {
    f(animal);
}
如何使这个代码具有多态性?它看起来不像猫或狗一样对待动物。

制作一个
f()
重载,将
动物*
作为输入,然后您的
for
循环将按照您编写的方式工作。然后要为
Dog
Cat
调用单独的
f()
重载,必须在运行时使用,例如:

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*
作为输入,然后您的
for
循环将按照您编写的方式工作。然后要为
Dog
Cat
调用单独的
f()
重载,必须在运行时使用,例如:

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
函数应该是
cat
dog
类的成员。由于设计的选择,我不希望f函数成为类的成员。同意指针的想法,如果你打算这样做,那么看看你需要使
f()
成为
Animal
的一个虚拟成员,如果你想要这种多态性,把单独的实现放在相应的
Cat
Dog
类中。你为什么要处理指向向量的指针?另外,
f
函数应该是
cat
dog
类的成员。由于设计的选择,我不希望f函数成为类的成员。同意指针的想法,如果你是这样做的,那么看看你需要做
f()
Animal的虚拟成员,如果您想要这种多态性,请将单独的实现放在相应的
Cat
Dog
类中。要避免添加太多的虚拟方法,还要避免添加太多的虚拟方法。
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();
}