研究完这个例子后我还有一个问题:C++ ecosystem simulator (inheritance) .
假设我有一个类似的示例,我想在其中使用 std::unique_ptr
。有没有办法在下面的示例中进行动态转换,而不必使用 std::unique_ptr
上的 .get()
来获取原始指针?我在代码中添加了两种变体:一种 (can_eat_1
) 以老式方式执行,另一种是在 中有
我想知道是否可以将其删除并用更优雅的方法替换(.get()
dynamic_castcan_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;
}
最佳答案
函数签名中智能指针的指导原则是,当且仅当函数关心智能指针本身时,即函数参与对象生命周期管理时,它们才应该出现在那里。
std::unique_ptr<Foo> f(); // Factory (gives an object to the caller)
void f(std::unique_ptr<Foo> &p); // Factory via output parameter
void f(std::unique_ptr<Foo> p); // Sink (takes an object from the caller)
就您而言,该函数会检查您的动物的属性。它根本不关心他们的生命周期。因此,智能指针不应出现在其签名中。
void f(Foo const &p); // Observe a Foo
void f(Foo const *p); // Observe a Foo
您使用哪一个指针或引用是一个品味问题,但这里通常选择的是引用。
can_eat_3(*rabbit, *wolf);
关于c++ - unique_ptr的继承和dynamic_cast,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36592131/