unique_ptr的继承和dynamic_cast
Inheritance and dynamic_cast of unique_ptr
在研究了这个例子之后,我还有一个问题:C++生态系统模拟器(继承)。
想象一下,我有一个类似的例子,我想使用std::unique_ptr
。有没有一种方法可以在下面的示例中进行动态强制转换,而不必使用std::unique_ptr
上的.get()
获取原始指针?我在代码中加入了两个变体:一个是以老式方式执行的(can_eat_1
),另一个是在dynamic_cast
中有一个.get()
,我想知道它是否可以被删除,并用更优雅的方法(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);
你可以通过参考资料试试这个:
bool can_eat_3(Animal const& predator, Animal const& prey)
{
return
dynamic_cast<Carnivore*>(&predator)
&&
dynamic_cast<Herbivore*>(&prey);
}
并通过以下方式调用:
can_eat_3(*wolf, *rabbit);
如果你取消引用并获得地址,你也可以使用can_eat_1:
can_eat_1(&*wolf, &*rabbit);
然而,我并不认为这"更优雅"。。。
相关文章:
- 如何理解C++标准N3337中的expr.const.cast子句8
- C++Cast运算符过载
- 在成员dynamic_bitset上使用 boost::from_block_range 时出错,但在本地dynamic
- C++类中的二维"dynamic"数组?
- 错误:"cast"未命名类型void setCastDescription(std::string
- 通过使用 const-cast 的非常量引用来延长临时的寿命
- "(void) cast"与功能有什么区别 "__attributes__"来沉默未使用的参数警告?
- protobuf in C++ with dynamic binding for google::protobuf::M
- 警告的原因是什么:"when type is in parentheses, array cannot have dynamic size"?
- C++:"Expected '(' for function-style cast or type construction"错误
- 为什么选择 g++ 给予者:"error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]"
- CUDA 错误:"dynamic initialization is not supported for __device__, __constant__ and __shared__ variabl
- Gtk+ g_signal_connect() 和 C++ lambda 会导致"invalid cast"错误
- 如何修复'The procedure entry point SDL_RWclose could not be located in the dynamic link library'
- Shared_ptr cast vs static_cast speed
- 在 iOS 上使用 Aruco 构建 OpenCV 时"Functional-style cast from id to double is not allowed"
- "The ordinal 344 could not be located in the dynamic link library"
- 覆盖 CAST 运算符(我认为它被称为向下转换)
- Dynamic Cast C++ Fail
- dynamic-cast-c++dynamic_cast错误处理