[英]c++ polymorphism with dynamic_cast and typeid
假设我有一个父class Shape
和两个子class Square
和class Circle
。
在我的代码中的某些时候,我会执行以下操作:
Shape* genericshape;
if(a_time_consuming_test()){
genericshape = new Square;
} else {
genericshape = new Cricle;
}
之后,我想创建另一个Circle或Square,但是我不想调用a_time_consuming_test()
。 那么我可以使用typeid
或其他等效形式直接创建“正确的”形状吗? 就像是 :
if(typeid(genericshape) == typeid(Square)){
Square newsquare;
} else {
Circle newcircle;
}
我想应该有这种解决方案,但这似乎并不有效,因为当我有第三个形状(如Triangle
那一天,我需要检查每个Shape
子Shape
。 这样的事情可能吗?
Shape* newshape(&genericshape);
我的意思是, newshape
将成为与genericshape
newshape
在同一子类上的指针吗?
查看答案之一,我应该指定Shape
, Square
和Circle
实际上是模板类。
我相信您正在寻找的是一种简单的克隆功能,但略有不同,即不会克隆数据,而只会克隆类型。 因此,您可以在Shape
添加以下内容:
struct Shape
{
virtual std::unique_ptr<Shape> createEmptyObject() const = 0;
// The rest as before
}:
struct Circle
{
std::unique_ptr<Shape> createEmptyObject() const override
{ return std::make_unique<Circle>(/*ctor args here*/); }
// The rest as before
};
然后像这样使用它:
Shape* genericshape;
if(a_time_consuming_test()){
genericshape = new Square;
} else {
genericshape = new Cricle;
}
// ...
auto anotherShape = genericshape->createEmptyObject();
注意:如果您无权使用C ++ 14,则必须用手动构建的unique_ptr
替换make_unique
:
return std::unique_ptr<Shape>(new Circle(/*ctor args here*/));
如果您准备编辑以下类型列表,则每次添加新形状时:
using shapes = typelist<circle, rectangle>;
那么我认为以下解决方案应该可以解决(逐步说明):
shape* create(shape const * s)
{
return create_impl(shapes(), s);
}
其中create_impl
和其他支持定义为:
template<typename T, typename ... Ts>
struct typelist{};
using shapes = typelist<circle, rectangle>;
template<typename T, typename ...Rest>
shape* create_impl(typelist<T, Rest...>, shape const *s)
{
if ( typeid(T) == typeid(*s) )
return new T();
else
return create_impl(typelist<Rest...>(), s);
}
template<typename T>
shape* create_impl(typelist<T>, shape const *s)
{
return typeid(T) == typeid(*s)? new T() : nullptr;
}
以后,如果您添加一个新形状,比如说triangle
,那么只需将其添加到类型列表中即可:
using shapes = typelist<circle, rectangle, triangle>;
然后一切都应该重新工作。 没有其他代码更改。
当然,您应该使用智能指针而不是原始指针,但是我想这是上面代码中的一个小修改。 基本思想将保持不变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.