-1

I have a function where I want to add pointers into a vector.

#include "Car.hpp"
using namespace std;

bool CarManagementSystem::addCar(Car::CarType new_car_type) {
    if (Car::CarType(new_car_type) == (Invalid)) {  
       return false;
    }
    else{
       new Car::CarType(new_car_type);
       carVector.push_back(Car::CarType(new_car_type));
       return true;
    }
}

The push_back command is giving me a lot of grief as in to what form I want the constraints to be in. I want to be able to use this function to create different types of my object Car, however am unsure how to do this.

The car class is purely virtual base class for all my different types of cars.

#include "Car.hpp"

Car::~Car() {
}

Car::CarType Car::type() const {
    return AT_INVALID;
}



class CarSystem {
private:
    double Balance;
    double CarCost;
    std::vector<Car*> carVector; 
...
Christophe
  • 68,716
  • 7
  • 72
  • 138
AmatuerCoder101
  • 59
  • 1
  • 10
  • 2
    First, are you sure you need a pointer? Second it sounds like you need a [good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) to get to learn the correct syntax of C++ – NathanOliver Aug 18 '16 at 12:04
  • 4
    This code is pretty weird - for example, the only purpose of `new Car::CarType(new_car_type);` is to create a memory leak. – Oliver Charlesworth Aug 18 '16 at 12:04
  • Please try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) and show us. Including the definition (or at least declaration) of `carVector`. – Some programmer dude Aug 18 '16 at 12:06
  • 1
    It seems you're still learning the basics of C++. You might want to grab a [good book](http://stackoverflow.com/q/388242/1782465) to get a firmer grasp on the fundamentals. – Angew is no longer proud of SO Aug 18 '16 at 12:08
  • You should probably have the `new` *inside* the `push_back()`, not outside. You could also possibly have a `std::vector` and not bother with pointers. – Bo Persson Aug 18 '16 at 12:23

2 Answers2

2

Your vector should be a vector of Car*:

std::vector<Car*> carVector;

The vector should be filled with concrete versions of the cars, meaning classes that are derived from base class Car:

class Van : public Car
{
   ...
};

...

Van* newVan = new Van();

carVector.push_back(newVan);

Here Van* is also a Car*. Make sure that you delete the contents of the vector at some point, or use smart pointers.

A better solution might be to have an enum inside the Car class that states the type of car, and then you don't need to deal with pointers.

Eyal K.
  • 1,042
  • 8
  • 23
  • 2
    _"A better solution might be to have an enum inside the Car class that states the type of car,"_ It's arguable whether that's better. Storing raw pointers in a `vector` is definitely not good, it should be `std::vector>` or `std::vector>`. – Jonathan Wakely Aug 18 '16 at 12:50
  • I mentioned the use of smart pointers. It's hard to give much concrete advice here when we don't have much information to go on. – Eyal K. Aug 18 '16 at 12:58
0

The trouble you have is that this code fragment doesn't do what you think:

   new Car::CarType(new_car_type);
   carVector.push_back(Car::CarType(new_car_type));
  • The first line creates a pointer to a new CarType object (an enum, an int, I don't know how you've defined it). This pointer is immediately lost and will cause memory leaks.

  • The second line tries to push_back a CarType object, which obviously is not a pointer.

What you are missing in your code is a factory function, which takes a CarType and which constructs a concrete car. It is not clear in your code if Car is an abstract type that can't be instantiated, or if it is a concrete class with some variations around the CarType.

If Car has a constructor that takes the CarType as parameter you'd need to do something like:

bool CarManagementSystem::addCar(Car::CarType new_car_type) {
    ...
    else{
       carVector.push_back(new Car(new_car_type));
       return true;
    }
}

But if Car is an abstract type with derived classes, you'd go for something like:

bool CarManagementSystem::addCar(Car::CarType new_car_type) {
    Car *c; 
    switch (new_car_type) {
      case AT_SUV: 
           c = new SUV;  // if SUV would be a class derived from Car  
           break; 
      case AT_RACING_CAR: 
           ...
      case AT_INVALID: 
      default: 
           return false;  
    }
    carVector.push_back(c);
    return true;
}

You may in this case be interested in a nice factory method pattern implementation such as the one explained in this tutorial.

Christophe
  • 68,716
  • 7
  • 72
  • 138