简体   繁体   中英

C++ polymorphism in simple example

I have this set of classes.

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;
};

Now I want to have

vector<Animal*> animals;

and few functions that are declared as follows:

void f(Dog* dog);
void f(Cat* cat);

and this code:

for (auto animal: animals) {
    f(animal);
}

how to make polymorphism out of this code? It looks like animal is not treated like cat or dog.

Make an f() overload that takes an Animal* as input, then your for loop will work as you have written it. To then call separate f() overloads for Dog and Cat , you will have to use dynamic_cast at runtime, eg:

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);
}

However, this goes against the principles of polymorphism. If f() needs to do different things depending on the type of Animal it is called on, it should be a virtual method of the Animal class, and then descendants can override it as needed:

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM