Reputation: 25
First off, I'm new to c++, currently learning it online. I greatly appreciate any help...
I have a vector of classes set up for vehicles, however it should also contain derived classes for vehicles of different types (car, truck, van).
My class is set up to have functions to gather user input and assign that to different variables, I do not use the constructor for this. Is that wrong?
In my main this all works fine and dandy but when I go to add the class to the vector I run into issues, first off, My instructor informed us to use smart pointers for this, so I initialize my vector like so...
vector<unique_ptr<Vehicle>> vehicles;
This is how I'm adding classes to that vector...
// For base class...
vehicles.push_back(make_unique<Vehicle>());
// For derived class...
vehicles.emplace_back(make_unique<Car>());
This is where I am stuck, adding the class this way will cause it to be called and therefor the constructor called as well. What I would like to do is just add a class that I have already created and defined beforehand, for example..
// Functions to gather user input, validate and display...
Vehicle vehicle;
vehicle.getMake();
vehicle.validateName(vehicle.make);
vehicle.getModel();
vehicle.validateName(vehicle.model);
vehicle.displayVehicle();
vehicles.push_back(/* Somehow add 'vehicle' */);
Thanks for any help, I understand this might be the wrong way to do this, I was just struggling to find a solution and this is currently where I am at.
Upvotes: 1
Views: 69
Reputation: 17454
My class is set up to have functions to gather user input and assign that to different variables, I do not use the constructor for this. Is that wrong?
A constructor shouldn't do lots of things, and never prompt for user input… but, at the same time, it should not be possible to have a "half-ready" object at any point. I suggest you gather all your user input first, then pass it into the constructor so your object is ready to go in one step.
(I have not shown this in the following example.)
This is where I am stuck, adding the class this way will cause it to be called and therefor the constructor called as well. What I would like to do is just add a class that I have already created and defined beforehand, for example..
Your vector contains unique_ptr<Vehicle>
s, so you'll want to start off with one:
std::unique_ptr<Vehicle> vehicle = std::make_unique<Vehicle>();
vehicle->getMake();
vehicle->validateName(vehicle->make);
vehicle->getModel();
vehicle->validateName(vehicle->model);
vehicle->displayVehicle();
vehicles.push_back(std::move(vehicle));
Notice that all the vehicle.
are now vehicle->
, because vehicle
is no longer an actual Vehicle
but instead a pointer to one.
std::move
is needed because unique_ptr
s are not copyable, only moveable.
Taking my advice from the start of the answer, this gets somewhat simpler:
std::string make = GetMake();
ValidateName(make);
std::string model = GetModel();
ValidateName(model);
vehicles.push_back(std::make_unique<Vehicle>(make, model));
vehicles.back()->displayVehicle();
I've moved the displayVehicle
call to the end, because it shouldn't make a difference to your output, but allows us to do the "construct Vehicle
" and "put it into vehicles
" steps simultaneously.
This approach assumes that you have altered your constructor to take make
and model
, and set up free function GetMake()
, GetModel()
and ValidateName()
to do those tasks.
Upvotes: 1