在下面的示例中,使用指针给我带来了一些我想避免的复杂情况。所以我想知道处理这种情况的正确方法是。
所以我有一个名为
Cars
的结构。它是一个容纳 Car
类对象的容器。具体来说, Cars
类有一个成员变量,它将所有 Car
对象存储在向量中。 Cars 的实例化存在于需要访问 Cars 中可变数量的 Car 对象的模拟范围内。
为了描述我的问题,这里有一个汽车鸣笛的模拟示例。虽然我知道下面的示例可以通过许多明显的方式进行改进,以更好地模拟汽车鸣笛,但请记住,这个示例的目的是展示一个更复杂的模拟的结构,我不能对其结构进行太大的改变。
struct Car {
public:
std::string id_;
std::string make_;
Car(const std::string& id, const std::string make) : id_(id) make_(make) {}
void honk(){
std::cout<<"Car "<<id_<<" honked!"<<std::endl;
};
};
class Cars {
private:
std::vector<Car> garage;
public:
void addCar(const Car& car) {
cars.push_back(car);
}
// Returns reference to element in garage vector
Car& get_car_by_id(const std::string id){
for (Car& car: garage) {
if (car.id_ == id) return car;
}
}
// Returns a vector of pointers to elements in garage vector
vector<std::unique_ptr<Car>> get_cars_by_make(const std::string &make) {
vector<std::unique_ptr<Car>> subset;
for (Car& car: garage) {
if (car.make == make) {
subset.push_back(std::make_unique<Car>(car));
}
}
return subset;
}
};
在下面的小模拟中,我们使用两种不同的 getter 方法来访问 Car 对象:通过单个引用来访问单个对象,然后通过智能指针向量来根据某些可以随时更改的条件来访问可变数量的对象模拟。后者是我问题的关键。
int main() {
Cars fleet;
fleet.addCar(Car("1", "Toyota"));
fleet.addCar(Car("2", "Toyota"));
fleet.addCar(Car("3", "Tesla"));
// Honk horn for car 3
Car& car fleet.get_car_by_id("3");
car.honk();
// Honk all of the Toyota's horns
vector<std::unique_ptr<Car>> cars = garage.get_by_make("Toyota");
for (const auto car : cars) {
car.honk();
}
}
我的问题是:有没有更好的方法来提供对这些 Car 对象的访问?我一直在尝试尽可能避免使用指针,但我觉得它们是唯一有意义的东西。如果没有提供对象的索引值而不是指针(这听起来很恶心),我不知道该怎么做。
get_cars_by_make()
不会返回指向车库中汽车的指针向量。它返回一个指向新车的唯一指针向量,这些新车是从车库中的汽车复制构建的。
如果您想将指针返回到车库中已有的汽车,请返回
vector<Car*>
而不是 vector<unique_ptr<Car>>
。
编辑:我意识到这是一个最小的示例,但是如果
get_cars_by_make()
除了线性搜索之外不执行任何操作,则该方法不会执行客户端无法为自己执行的任何操作(如果它可以看到向量迭代器)。如果您导出这些迭代器(理想情况下作为范围,但可能使用开始/结束方法,甚至返回对向量的引用),那么客户端可以通过 make 找到,而无需分配向量来保存结果。