gpt4 book ai didi

c++ - 在 C++ std:: 容器中存储多种类型结构的模式

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:25:06 25 4
gpt4 key购买 nike

我有一个表示火车的数据结构,它可以由多种类型的汽车组成,例如火车引擎、运粮车、客车等:

struct TrainCar {
// ...
Color color;
std::string registration_number;
unsigned long destination_id;
}

struct PowerCar : TrainCar {
// ...
const RealPowerCar &engine;
}

struct CargoCar : TrainCar {
// ...
const RealCargoCar &cargo;
bool full;
}

std::vector<TrainCar*> cars;
cars.push_back(new TrainCar(...));
cars.push_back(new TrainCar(...));
cars.push_back(new CargoCar(...));
cars.push_back(new CargoCar(...));
cars.push_back(new CargoCar(...));

一种算法将遍历火车中的车厢,并决定如何安排/调车每节车厢(是否将其保留在火车中、将其移动到火车中的另一点、将其从火车中移除)。此代码如下所示:

std::vector<TrainCar*>::iterator it = cars.begin();
for (; it != cars.end(); ++it) {
PowerCar *pc = dynamic_cast<PowerCar*>(*it);
CargoCar *cc = dynamic_cast<CargoCar*>(*it);

if (pc) {
// Apply some PowerCar routing specific logic here
if (start_of_train) {
// Add to some other data structure
}
else if (end_of_train && previous_car_is_also_a_powercar) {
// Add to some other data structure, remove from another one, check if something else...
}
else {
// ...
}
}
else if (cc) {
// Apply some CargoCar routing specific logic here
// Many business logic cases here
}
}

我不确定这种模式(使用 dynamic_casts 和 if 语句链)是否是处理不同类型的简单结构列表的最佳方式。 dynamic_cast 的使用似乎不正确。

一个选择是将路由逻辑移动到结构中(例如 (*it)->route(is_start_of_car, &some_other_data_structure...)),但是如果可能的话,我想将路由逻辑放在一起。

是否有更好的方法来遍历不同类型的简单结构(没有方法)?还是保留 dynamic_cast 方法?

最佳答案

对此的标准解决方案称为 double-dispatch .基本上,您首先将算法包装在为每种类型的汽车重载的单独函数中:

void routeCar(PowerCar *);
void routeCar(CargoCar *);

然后,在基类中为纯虚拟的 car 添加一个 route 方法,并在每个子类中实现:

struct TrainCar {
// ...
Color color;
std::string registration_number;
unsigned long destination_id;

virtual void route() = 0;
}

struct PowerCar : TrainCar {
// ...
const RealPowerCar &engine;
virtual void route() {
routeCar(this);
}
}

struct CargoCar : TrainCar {
// ...
const RealCargoCar &cargo;
bool full;
virtual void route() {
routeCar(this);
}
}

你的循环看起来像这样:

std::vector<TrainCar*>::iterator it = cars.begin();
for (; it != cars.end(); ++it) {
(*it)->route();
}

如果您想在运行时在不同的路由算法之间进行选择,您可以将 routeCar 函数包装在一个抽象基类中,并为此提供不同的实现。然后,您将该类的适当实例传递给 TrainCar::route

关于c++ - 在 C++ std::<vector> 容器中存储多种类型结构的模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7722359/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com