C++继承问题:Car实例加入Lane后起始位置未设为5的解决求助
让我们一步步排查你遇到的问题,先梳理核心逻辑:你的Car带参数构造函数中,先调用Vehicle(position),再通过SetStartingPosition(5)把起始位置设为5,理论上新创建的Car实例起始位置应该是5,但实际没得到预期结果,可能的原因如下:
1. Vehicle带参数构造函数的实现不明确
你在Vehicle.h中声明了Vehicle(double position)构造函数,但没有给出具体实现。如果这个构造函数没有正确初始化fStartingPos,会导致成员变量处于未定义的垃圾值状态——虽然后续Car构造函数的SetStartingPosition(5)会覆盖这个值,但未初始化的内存可能引发不可预测的行为。
建议补全Vehicle.cpp中该构造函数的实现,确保基类初始化逻辑明确:
Vehicle::Vehicle(double position) : fStartingPos(position) {}
2. Car默认构造函数未设置起始位置
你在Car.h中声明了Car()默认构造函数,但Car.cpp中没有给出实现。如果你在某个场景下通过new Car()创建实例(而非带参数的Car(double position)),这个默认构造函数不会调用SetStartingPosition(5),导致起始位置是Vehicle默认构造初始化的值(比如0或未定义值)。
如果需要默认构造的Car也拥有起始位置5,补全Car.cpp中的默认构造:
Car::Car() { SetStartingPosition(5); }
3. Lane::AddRandomVehicle存在越界访问风险
看Lane.cpp的这段代码:
void Lane::AddRandomVehicle(){ int i = 0; AddVehicleToALane(new Car(fVehicles[i]->GetStartingPosition())); }
如果fVehicles是空的,fVehicles[i]会直接访问越界内存,触发未定义行为——程序可能崩溃,或者读取到随机值传入Car构造函数。虽然这不会影响Car最终把位置设为5的逻辑,但这个漏洞必须修复,比如先判断容器是否为空:
void Lane::AddRandomVehicle(){ if (fVehicles.empty()) { // 空容器时默认创建起始位置5的Car AddVehicleToALane(new Car(0)); return; } // 也可以改成随机索引,比如rand() % fVehicles.size() int i = 0; AddVehicleToALane(new Car(fVehicles[i]->GetStartingPosition())); }
4. 你调用GetStartingPosition()的对象并非新创建的Car
你的Lane类中有成员变量Vehicle *v;,但AddVehicleToALane方法只是把传入的vehicle加入fVehicles,并没有给v赋值。如果你是通过lane.v->GetStartingPosition()来获取值,那v可能指向旧对象,甚至是未初始化的野指针,自然得不到新Car的5。
如果要获取刚添加的Car的起始位置,应该从fVehicles中取最后一个元素:
// 示例:添加完车辆后获取位置 lane.AddRandomVehicle(); if (!lane.fVehicles.empty()) { double pos = lane.fVehicles.back()->GetStartingPosition(); // 这里应该能得到预期的5 }
快速验证核心逻辑
你可以写一段简单的测试代码,先确认Car构造函数的行为是否正确:
#include <iostream> #include "Car.h" int main() { Car testCar(100); // 传入任意值,构造函数会把位置设为5 std::cout << testCar.GetStartingPosition() << std::endl; // 预期输出5 return 0; }
如果这段代码输出5,说明Car和Vehicle的逻辑是正确的,问题就出在Lane类的使用或越界访问上;如果输出不是5,那就要重点检查Vehicle的构造函数实现、SetStartingPosition的逻辑是否有隐藏问题。
内容的提问来源于stack exchange,提问作者L. Howard

