繁体   English   中英

具有dynamic_cast和typeid的C ++多态

[英]c++ polymorphism with dynamic_cast and typeid

假设我有一个父class Shape和两个子class Squareclass 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那一天,我需要检查每个ShapeShape 这样的事情可能吗?

Shape* newshape(&genericshape);

我的意思是, newshape将成为与genericshape newshape在同一子类上的指针吗?

编辑

查看答案之一,我应该指定ShapeSquareCircle实际上是模板类。

我相信您正在寻找的是一种简单的克隆功能,但略有不同,即不会克隆数据,而只会克隆类型。 因此,您可以在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM