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

用户4833046

我有这组课程。

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()Dogand调用单独的重载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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章