You need to enable JavaScript to run this app. C++如何将继承同一父类的不同子类对象存储到同一个数组中
优惠活动
大模型
产品
解决方案
定价
更多

C++如何将继承同一父类的不同子类对象存储到同一个数组中

问题原因分析
  • 你将子类实例地址赋值给父类指针Vehicle*后,父类指针的静态类型为Vehicle,仅能访问Vehicle类中定义的成员,子类独有的currentMileage、motorType等成员无法直接访问,所以触发编译报错
  • 额外问题:你声明的vehicleID和man是Vehicle的私有成员,子类/外部无法直接访问;同时用%c打印string类型的man属于格式符不匹配,运行会出错
可行解决方案

方案1:使用虚函数实现多态(最推荐,符合面向对象设计)

在父类中定义虚接口,不同子类各自实现对应逻辑,不需要暴露子类独有成员,也不需要强制类型转换:

class Vehicle {
private:
    string vehicleID;
    string man;
public:
    Vehicle(string, string);
    Vehicle();
    // 新增get方法访问私有成员
    string getVehicleID() const { return vehicleID; }
    string getMan() const { return man; }
    // 定义虚接口,子类各自实现
    virtual void printInfo() const {
        printf("车辆ID:%s,厂商:%s\n", getVehicleID().c_str(), getMan().c_str());
    }
    virtual ~Vehicle();
};

class Bus: public Vehicle
{
public:
    int currentMileage;
    Bus(string, string, int);
    Bus();
    // 重写虚接口
    void printInfo() const override {
        printf("巴士:ID %s,厂商 %s,当前里程 %d\n", getVehicleID().c_str(), getMan().c_str(), currentMileage);
    }
    virtual ~Bus();
};

class Train: public Vehicle
{
public:
    char motorType;
    Train(string, string, char);
    Train();
    void printInfo() const override {
        printf("火车:ID %s,厂商 %s,动力类型 %c\n", getVehicleID().c_str(), getMan().c_str(), motorType);
    }
    virtual~Train();
};

使用时直接调用虚函数即可:

Vehicle* arrVehicle[2];
arrVehicle[0] = new Bus("001", "巴士厂商", 12000);
arrVehicle[1] = new Train("002", "火车厂商", 'E');

for(int i=0; i<2; i++) {
    arrVehicle[i]->printInfo(); // 自动调用对应子类的实现
}

// 记得释放内存避免泄漏
for(int i=0; i<2; i++) {
    delete arrVehicle[i];
}

方案2:向下转型访问子类独有成员

如果确实需要单独访问子类独有的成员,可以用dynamic_cast做安全类型转换,转换前会做类型校验,转换失败返回空指针:

Vehicle* arrVehicle[2];
arrVehicle[0] = new Bus("001", "巴士厂商", 12000);
arrVehicle[1] = new Train("002", "火车厂商", 'E');

// 尝试转换为Bus类型
Bus* busPtr = dynamic_cast<Bus*>(arrVehicle[0]);
if(busPtr != nullptr) {
    printf("%i\n", busPtr->currentMileage);
    printf("%s\n", busPtr->getMan().c_str());
}

// 尝试转换为Train类型
Train* trainPtr = dynamic_cast<Train*>(arrVehicle[1]);
if(trainPtr != nullptr) {
    printf("%c\n", trainPtr->motorType);
}

注意:使用dynamic_cast需要开启编译器的RTTI(运行时类型信息)支持,大部分编译器默认开启。

方案3:C++17及以上版本使用std::variant存储

不需要继承关系也可以存储不同类型的对象,用std::visit访问:

#include <variant>
#include <vector>

// 定义variant类型,可存储三种子类对象
using VehicleVariant = std::variant<Bus, Train, Helicopter>;
std::vector<VehicleVariant> arrVehicle;
arrVehicle.emplace_back(Bus("001", "巴士厂商", 12000));
arrVehicle.emplace_back(Train("002", "火车厂商", 'E'));

// 访问时用visit
for(auto& v : arrVehicle) {
    std::visit([](auto&& vehicle) {
        printf("厂商:%s\n", vehicle.getMan().c_str());
        // 判断类型访问独有成员
        if constexpr (std::is_same_v<std::decay_t<decltype(vehicle)>, Bus>) {
            printf("里程:%d\n", vehicle.currentMileage);
        } else if constexpr (std::is_same_v<std::decay_t<decltype(vehicle)>, Train>) {
            printf("动力类型:%c\n", vehicle.motorType);
        }
    }, v);
}

内容的提问来源于stack exchange,提问作者User Userus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 19:27:04