Austin Brown
Austin Brown

Reputation: 25

Is there a way to add a pre created class to a vector?

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

Answers (1)

Asteroids With Wings
Asteroids With Wings

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_ptrs 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

Related Questions