Ich habe eine Frage, die nach dem Studium dieses Beispiels bleibt: C++ ecosystem simulator (inheritance).Vererbung und dynamic_cast von unique_ptr
Stellen Sie sich vor, ich habe ein ähnliches Beispiel, wo ich mit der std::unique_ptr
arbeiten möchte. Gibt es eine Möglichkeit, das dynamische Casting im folgenden Beispiel auszuführen, ohne auf den rohen Zeiger mit der .get()
auf der std::unique_ptr
zurückgreifen zu müssen? Ich habe zwei Varianten in den Code: eine (can_eat_1
), die es die altmodische Art und Weise tut, und eine, wo ich eine .get()
in der dynamic_cast
für die ich frage, ob es entfernt und durch eine elegantere Methode ersetzt werden kann (can_eat_2
) :
#include <iostream>
#include <memory>
struct Animal
{
virtual ~Animal() {};
};
struct Carnivore : public Animal {};
struct Herbivore : public Animal {};
struct Wolf : public Carnivore {};
struct Rabbit : public Herbivore {};
bool can_eat_1(Animal* predator, Animal* prey)
{
return (dynamic_cast<Carnivore*>(predator) && dynamic_cast<Herbivore*>(prey));
}
bool can_eat_2(std::unique_ptr<Animal>& predator, std::unique_ptr<Animal>& prey)
{
return (dynamic_cast<Carnivore*>(predator.get()) && dynamic_cast<Herbivore*>(prey.get()));
}
int main()
{
std::unique_ptr<Animal> wolf (new Wolf );
std::unique_ptr<Animal> rabbit(new Rabbit);
std::cout << "Option 1: pass raw pointers:" << std::endl;
std::cout << "Wolf eats rabbit = " << can_eat_1(wolf.get(), rabbit.get()) << std::endl;
std::cout << "Rabbit eats wolf = " << can_eat_1(rabbit.get(), wolf.get()) << std::endl;
std::cout << "Option 2: pass unique_ptr:" << std::endl;
std::cout << "Wolf eats rabbit = " << can_eat_2(wolf, rabbit) << std::endl;
std::cout << "Rabbit eats wolf = " << can_eat_2(rabbit, wolf) << std::endl;
return 0;
}
Wo finde ich diese Richtlinie? Was du schreibst, ergibt für mich Sinn. – Chiel
@Chiel Sie finden diesen Rat auf [Herb Sutters Website] (https://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/). – Quentin
Der Verweis ist hier ein wenig peinlich, da es entweder einen "try" - und einen "catch" -Block erfordern würde, um eine Ausnahme zu erfassen, die für die Flusssteuerung nicht sehr elegant ist, oder eine Neufassung zurück zum Zeiger. Ich denke, ich werde auf die Hinweise eingehen. – Chiel