C++ 提取向量中的对象类型,然后在比较中使用。c++;

C++ 提取向量中的对象类型,然后在比较中使用。c++;,c++,qt,vector,C++,Qt,Vector,我有一个指向车辆的指针向量,其中包含汽车、卡车、摩托车等车辆。这些车辆具有与其关联的位置,这些位置使用QT中的drawPoint()进行跟踪和绘制。我想知道如何实现一种检查每个元素的对象类型的替代方法,即不使用typeid for (unsigned int jV = 0; jV < fRoadDisp->getCurrentLane(iLane)->getNVehiclesinLane(); jV++) { //QPainter painter(this)

我有一个指向车辆的指针向量,其中包含汽车、卡车、摩托车等车辆。这些车辆具有与其关联的位置,这些位置使用QT中的drawPoint()进行跟踪和绘制。我想知道如何实现一种检查每个元素的对象类型的替代方法,即不使用typeid

for (unsigned int jV = 0; jV < fRoadDisp->getCurrentLane(iLane)->getNVehiclesinLane(); jV++)
   {
       //QPainter painter(this); //already done outside loop
       QPen pointpenv(Qt::red);
       pointpenv.setWidth(5);
       QPen pointpenC(Qt::blue); // For a Car
       pointpenC.setWidth(5);
       QPen pointpenL(Qt::green); // For a Lorry
       pointpenL.setWidth(5);
       QPen pointpenM(Qt::yellow); // For a Motorcycle
       pointpenM.setWidth(5);

       double position = fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV)->getPosition();

       if(typeid(fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV)) == typeid(Car*)){painter.setPen(pointpenC);}
       else if(typeid(fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV)) == typeid(Lorry*)){painter.setPen(pointpenL);}
       else if(typeid(fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV)) == typeid(Motorcycle*)){painter.setPen(pointpenM);}

       painter.drawPoint(((iLane * (width()/fRoadDisp->getNLanes())) + width()/(2 *   fRoadDisp->getNLanes())), position * height()/300);
   }
for(unsigned int jV=0;jVgetCurrentLane(iLane)->getNVehiclesinLane();jV++)
{
//QPainter painter(此);//已在外循环中完成
QPen pointpenv(Qt::红色);
pointpenv.setWidth(5);
QPen pointpenC(Qt::蓝色);//用于汽车
点便士设置宽度(5);
QPen pointpenL(Qt::绿色);//对于卡车
pointpenL.setWidth(5);
QPen pointpenM(Qt::黄色);//用于摩托车
pointpenM.setWidth(5);
双位置=fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV)->getPosition();
如果(typeid(fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV))==typeid(Car*){painter.setPen(pointpenC);}
否则如果(typeid(fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV))==typeid(Lorry*){painter.setPen(pointpenL);}
否则如果(typeid(fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV))==typeid(摩托车*){painter.setPen(pointpenM);}
painter.drawPoint(((iLane*(width()/fRoadDisp->getNLanes())+width()/(2*fRoadDisp->getNLanes())),position*height()/300);
}
上述循环以指向车辆的指针向量覆盖所有车辆,仅为不同车辆提供不同颜色的笔,并且,根据正在绘制的车辆类型,我希望激活相应的笔

当前,任何点都显示为白色。一个可能的解决方案(我被告知)是使用静态公共变量,但我不确定如何实现它来代替typeid


任何帮助都将不胜感激。

我将通过以下方式解决此问题:

  • 声明一个抽象类
    车辆
    ,例如:

    class Vehicle
    {
    public:
      enum Type
      {
        Car,
        Lorry
      }    
      virtual Type getType() const = 0;
    };
    
  • 从该
    车辆
    类别派生所有车辆类别:

    class Car : public Vehicle
    {
      public:
      Type getType() const override { return Vehicle::Car; }
    };
    
  • 等等

  • 在绘图例程中,您只需:

    if (fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV)->getType == Vehicle::Car)
    {
      painter.setPen(pointpenC);
    }
    

  • 我喜欢vahancho建议的方法,但是,考虑到必要的重构,我不会在场景中添加枚举,并直接为抽象车辆提供penColor属性,以避免检查其类型:

    class Vehicle
    {
    public:
        virtual QColor penColor() const { return Qt::red; }
    };
    class Car : public Vehicle
    {
      public:
      QColor penColor() const { return Qt::blue; }
    };
    
    因此,您可以这样选择合适的笔:

    painter.setPen(QPen(fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV).penColor()));
    
    Vehicle v = fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV);
    QPen pen(v.drawingInfo().penColor);
    pen.setWidth(v.drawingInfo().penWidth);
    painter.setPen(pen);
    
    如果不需要,则不需要
    ,也不需要
    std::map

    但是,如果您认为penColor属性不完全属于车辆,则可以使用单独的类来保存图形信息:

    struct DrawingInfo
    {
        DrawingInfo() : penColor(Qt::red), penWidth(5){}
        DrawingInfo(QColor c) : penColor(c), penWidth(5){}
        DrawingInfo(QColor c, int w) : penColor(c), penWidth(w){}
    
        QColor penColor;
        int penWidth;
    };
    
    并给出车辆及其派生类的实例:

    class Vehicle
    {
    public:
        DrawingInfo drawingInfo() const { return _drawingInfo; }
    protected:
        DrawingInfo _drawingInfo;
    };
    class Car : public Vehicle
    {
    public:
        Car()
        {
            _drawingInfo.penColor = Qt::blue;
        }
    };
    
    这一次,您可以通过以下方式选择正确的笔:

    painter.setPen(QPen(fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV).penColor()));
    
    Vehicle v = fRoadDisp->getCurrentLane(iLane)->getCurrentVehicle(jV);
    QPen pen(v.drawingInfo().penColor);
    pen.setWidth(v.drawingInfo().penWidth);
    painter.setPen(pen);
    

    我会将颜色添加到车辆类别中

    class Vehicle : public QObject
    {
        public:
           Vehicle(QColor colour);
           QColor Colour() const;
    
        private:
            QColor m_vehicleColour;
    };
    
    这比存储实际的QPen更有意义,QPen不是车辆的属性

    我想知道如何实现一种检查每个元素的对象类型的替代方法,即不使用typeid

    如果您的车辆是QoObject,应注意您可以使用检索车辆类型

    假设我们从汽车中衍生出汽车

    Vehicle* pCar = new Car(Qt::red);
    if(pCar->metaObject() == "Car")
    {
        // This instance of vehicle is a car
    }
    
    当然,最好不要使用if(type)然后

    因此,渲染器现在可以创建具有正确颜色的QPen

    QPen pen(vehicle->Colour());
    

    通常情况下,这是使用多态性的一个候选方法,因为您的车辆似乎已经有了不同的类别,为什么不使用它们来获得颜色呢?您可以在车辆基础CAS中定义
    getColor()
    方法,并让所有子类返回不同的颜色,因此无需执行将
    Vehicle
    与绘图代码相耦合的typeid或switch等@xander。如果车辆类型集大部分是静态的,那么
    车辆导航器
    可能比在
    车辆
    中添加不相关的属性更好:“我有一个指针向量”:请使用智能指针,请使用智能指针,请使用智能指针….@UKMonkey Qt在这方面非常糟糕,在原始指针中转移所有权。“需要与C++98兼容的GUI层次结构”是有道理的,但会泄露到其他用途中:(@Caleth同意,但你仍然可以有一个平行的类层次结构用于绘图。类似于
    QtVehicle
    QtCar
    等。用
    std::map
    代替if链怎么样?是的,这也是一个好方法。不过问题是关于对象识别。如果使用了着色,这种方法会更简单应用程序需要知道车辆类型的唯一原因。然而,越需要区分车辆类型,它就越不简单vehicles@vahancho你说得很对,我编辑了答案以使问题更为顺利。@Caleth我想已经有很多方法可以做到这一点了(typeid,dynamic_cast,我们在这里讨论Qt时,元对象系统提供了一个QMetaObject::className(),可以满足这一需要)。如果您认为penColor属性不完全属于车辆,或者只是将车辆颜色存储为
    QColor
    ,而不是存储笔,那么将其传递给DrawingInfo类。