c++ - unique_ptr的继承和dynamic_cast

标签 c++ oop c++11

研究完这个例子后我还有一个问题:C++ ecosystem simulator (inheritance) .

假设我有一个类似的示例,我想在其中使用 std::unique_ptr。有没有办法在下面的示例中进行动态转换,而不必使用 std::unique_ptr 上的 .get() 来获取原始指针?我在代码中添加了两种变体:一种 (can_eat_1) 以老式方式执行,另一种是在 中有 .get() dynamic_cast 我想知道是否可以将其删除并用更优雅的方法替换(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;
}

最佳答案

函数签名中智能指针的指导原则是,当且仅当函数关心智能指针本身时,即函数参与对象生命周期管理时,它们才应该出现在那里。

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/

相关文章:

c++ - 如何为类 union 类编写析构函数

c++ - C++ 编译器能否消除未读取的 volatile 局部变量

c++ - char 和 wchar_t 之间的转换在 Windows 中如何工作?

c++ - C++ 的 Anagram 生成器(不使用 STL)

c++ - 使用构造函数初始化您的类,该构造函数将 std::map 作为带有大括号括起来的初始化程序的参数

java - 在java中如何使用类的字符串属性来引用该类?

matlab - 如何在matlab包中使用静态工厂方法?

python - 什么时候重构?

c++ - 在字符数组中插入新换行符

c++ - 是否存在太多包含路径这样的事情?