简体   繁体   中英

Proper Design to Avoid Use of Dynamic_Cast

I'm experiencing an issue very similar to the question asked here: Using derived methods that aren't in the base class

In that question, the top answer, provided by IdeaHat, is to use dynamic_cast, but then he/she goes on to say that if you have to resort to that, then your design is bad. I've noticed very similar answer in other questions.

So, then, what is the proper design in such a situation?

For the sake of discussion, let's use this code:

enum AnimalType {
    dog = 0,
    cat
}

Class Animal {
    virtual AnimalType getType() = 0;

    void eat() {
        cout << "Ate some food!" << endl;
    }

    void sleep() {
        cout << "Zzzz..." << endl;
    }
};

Class Dog : public Animal {
    AnimalType getType() {
        return AnimalType::dog;
    }

    void fetch() {
        cout << "Fetched the stick!" << endl;
    }
};

Class Cat : public Animal {
    AnimalType getType() {
        return AnimalType::cat;
    }
};

//A factory function
Animal* shelter(AnimalType type) {
    if(type == AnimalType::dog) {
        return new Dog;
    }
    else {
        return new Cat;
    }

int main() {
    Animal* pet = shelter(AnimalType::dog);

    pet->fetch();
}

Essentially, I have a factory producing multiple subclasses of a particular class. Some of the subclasses contain functions not present in the parent/other subclasses, which would prevent the use of polymorphism without a workaround.

How would I implement this in a fashion that works and would also be considered "good design"?

Easy:

void functionTakingAnimal(Animal& a) {
    a.eat();
    a.sleep();
}

int main() {
    Dog pet;
    pet.fetch();
    functionTakingAnimal(pet);
}

Don't destroy static type information earlier than you need to.

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