In the following example, using pointers has caused me some complications that I'd like to avoid. So I'm wondering that the correct way of dealing with this situation would be.
So I have a struct called Cars
. It's a container to hold objects of class Car
. Specifically, The Cars
class has a member variable that stores all of the Car
objects in a vector. An instantiation of Cars exists in the scope of a simulation that needs to access a variable number of Car objects within Cars.
To describe my issue here is an example sim of cars honking. While I know the following example can be improved in many obvious ways to better simulate cars honking, keep in mind this example's purpose is to show the structure of a much more complicated simulation whose structure I cannot broadly alter very too much.
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;
}
};
In the following small simulation we use the two different getter methods to access Car objects: via a single reference to access an individual object, and then a vector of smart pointers to access a variable number of objects based on some condition that can change throughout the simulation. The latter is the crux of my issue.
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();
}
}
My question is this: Is there a better way to provide access to these Car objects? I've been trying to avoid pointers as much as possible but I feel like they're the only thing that makes sense. Short of providing the index values of the objects instead of pointers (which sounds disgusting), I'm not sure what to do.