将派生类中的对象插入到所述对象的另一个实例中(使用 vector.insert 函数)C++

Posted

技术标签:

【中文标题】将派生类中的对象插入到所述对象的另一个实例中(使用 vector.insert 函数)C++【英文标题】:Inserting an object from a derived class into another instance of said object (using the vector.insert function) C++ 【发布时间】:2017-12-06 11:51:42 【问题描述】:

我目前正在处理具有 Road 类的代码。这有一个车道向量并包括一个车道类别。车道类有一个车辆向量,每辆车都有其派生类(汽车、摩托车、货车)。 我希望车辆能够评估它是否可以进入另一条车道,即安全地插入另一条车道的车辆矢量(汽车需要一定的安全距离,所以我已经实现了车辆如何知道它是否清晰切换车道)。

void Road::Simulate(double time)


for (unsigned int iLane = 0; iLane < getNLanes()-1; iLane++)

    for (unsigned int iV = 0; iV < getCurrentLane(iLane)->getNVehiclesinLane(); iV++)
    
        std::cout<< " AllowedOvertake TEST "<<   getCurrentLane(iLane+1)->allowedOvertake(getCurrentLane(iLane)->getCurrentVehicle(iV)->getPosition(), getCurrentLane(iLane)->getCurrentVehicle(iV)->getMinDistance())<<std::endl;
        getCurrentLane(iLane+1)->setCanOvertake(allowedOvertake(getCurrentLane(iLane)->getCurrentVehicle(iV)->getPosition(), getCurrentLane(iLane)->getCurrentVehicle(iV)->getMinDistance()));

        if (getCurrentLane(iLane+1)->getCanOvertake() == true)
        
            getCurrentLane(iLane+1)->insertVehicle(getCurrentLane(iLane)->getCurrentVehicle(iV), 0);
            delete getCurrentLane(iLane)->getCurrentVehicle(iV);
        

    

for (unsigned int iLane = 0; iLane < getNLanes(); iLane++)

    getCurrentLane(iLane)->Simulate(time);

我会遍历所有当前车道,除了最后一条,因为该车道上的任何车辆都无法超车。在遍历每条车道中包含的车辆后,我有一个函数返回一个布尔值,用于确认是否可以执行超车场景。这是在allowedOvertake() 中完成的。如果返回 true,我实现了一个插入函数。

我的问题/问题:我怎样才能使这种意识形态发挥作用,以及拥有这些 setCanOvertake()getCanOvertake() 功能是否明智。

一种可能的解决方案可能是将一辆新车推回预定车道,但要使用适当的位置、速度等。但是,我不确定如何确保进入的车辆具有相同的类型(汽车、货车...) 也是。

目前,如果我排除 insertVehicle() 函数,我不会收到任何构建错误,并且我使用 QPainter 绘制了车辆运动。但是,使用 insertVehicle() 函数时,我没有收到任何构建错误,但运行项目后确实会崩溃。

任何帮助都将不胜感激,并对任何编码错误表示歉意(我是一个热心但非常缺乏经验的 C++ 用户)。

作为参考,我将上述函数的定义如下

bool Lane::allowedOvertake(double pos, double mindist)

    for (unsigned int iV = 0; iV < getNVehiclesinLane() - 1; iV++)
    
        if ((fVehicles[iV]->getPosition() > pos - mindist)// If inside rear safety distance.
            || fVehicles[iV]->getPosition() < pos + mindist)// If inside front safety distance.
       //continue
    else return false;
    
return true;


//IN Lane.h
bool getCanOvertake() constreturn FREE_LANE_OVERTAKE;
//IN Lane.h
void setCanOvertake(bool overtake = true)FREE_LANE_OVERTAKE = overtake;

【问题讨论】:

我认为问题出在delete getCurrentLane(iLane)-&gt;getCurrentVehicle(iV); 行。您不需要删除对象本身,只需将指向该对象的指针从一个容器移动到另一个容器 - 插入指向新容器的指针并将其从另一个容器中删除 嗨@vahancho,即使没有这条线,只是有一个插入功能,应该只是复制车辆,仍然会导致崩溃。我不确定如何使用 remove 函数,以及为什么应该使用它而不是 delete 正如@vahancho 提到的,看起来删除不正确。据我所知,您正在将车辆移动到另一条车道,然后将其删除。您需要将其从之前的车道车辆矢量中移除。删除一个对象不会将它从包含它的任何向量中删除,而是会释放该对象使用的内存,并且任何后续尝试使用它都将无效并导致崩溃。您可以使用 std::vector::erase() 函数从向量中删除对象。 我仍然不确定这个解释。我只删除在前车道上的车辆。我使用的insertVehicle 函数创建了一个与应该移动的具有相同属性的新车辆,因此,一旦我使用它,我当然可以删除与前车道对应的对象(在第 i 个车道中删除,而不是 (第 i+1) 个车道)。我可能不理解您对删除和擦除之间区别的解释,如果是这种情况,我深表歉意。会不会是我的 `insertVehicle() 函数不正确,因为我只插入了一辆车,它在一开始就变道了。 @KarandeepGiddha,那么请说明insertVehicle()函数是如何实现的。 【参考方案1】:

抱歉,我的印象是我引用了我的 insertVehicle() 函数定义。

void Lane::insertVehicle(Vehicle*v, int ielement) 

    Vehicle* vins = new Vehicle(v->getPosition(), v->getVelocity(), v->getAcceleration());

    for (unsigned int iDist = 0; iDist < fVehicles.size()+1; iDist++)fVehicles.insert(fVehicles.begin() + (ielement+1), vins);

【讨论】:

为什么要创建车辆副本?您可以简单地将指向它的指针插入到fVehicles 向量中,然后从之前存储的位置(其他通道的fVehicles 向量)中删除相同的指针。此外,您插入的for 循环看起来很奇怪。 是的,我可以清楚地看到我不需要复制我的车辆。我已将insertVehicle() 更改为现在直接接收车辆的指针。我还注意到一个错误,我不应该遍历insertVehicle() 内的所有车辆。这个函数应该只是插入一个车辆。

以上是关于将派生类中的对象插入到所述对象的另一个实例中(使用 vector.insert 函数)C++的主要内容,如果未能解决你的问题,请参考以下文章

如何将一个对象插入到mongo数组中的另一个对象中

C++如何使用派生类构造函数销毁基类中的对象

C++ 类型将基础对象转换为派生对象

在 C# 中的另一个对象内实例化用户定义的对象

C#:基类中的受保护方法;无法使用来自另一个类的派生类对象进行访问[重复]

更改派生对象中的基础对象