Search code examples
c++dynamic-arrays

C++ Dynamic Array for Class Object of different variable types


I'm trying to write a dynamic array that will allow me to enter a unique number of vehicles through the function addVehicle but im struggling on how to use the array and add items to it.

I read that dynamic arrays are created through the use of a vector function but im a bit confused on how it works, additionally as you can see my vehicle class has different variable types, will that interfere?

#include <iostream>
#include <vector>

//Silo Storage System

class Silo {
    public:
        std::string name;
        int currentVolume;
        int storageVolume;
};

class Vehicle {
    public:
        std::string model;
        int capacity;
};


void addVehicle(std::vector<vehicle>& vehicle){
    vehicle v;

    
    //std::cout << "Please specify number of vehicles to add" << endl;
    
    std::cout << "Please specify the vehicle model" << std::endl;
    std::cin >> v.model;
    std::cout << "Please specify the load capacity" << std::endl;
    std::cin >> v.capacity;
    
    vehicle.push_back(v);
};


int main() {
    
    Silo depoSilos[3] = {
    {"Silo 1 - Aggregate", 1400,  40000},
    {"Silo 2 - Aggregate", 2300,  20000},
    {"Silo 3 - Aggregate", 11000,  40000}
    };
    
    std::cout << "No. of available silos: " << *(&depoSilos + 1) - depoSilos << std::endl;
    for (int i = 0;i < *(&depoSilos + 1) - depoSilos; i++) {
        std::cout << depoSilos[i].name << " is " << static_cast<double>(depoSilos[i].currentVolume) / static_cast<double>(depoSilos[i].storageVolume) * 100 <<
        "% full." << " Max capacity: " << depoSilos[i].storageVolume << std::endl;
    };

    std::vector<Vehicle> vehicles;
    addVehicle(vehicles);
    
    return 0;
}

Solution

  • To achieve this, you'll need to:

    1. Prompt the user for the number of vehicles to create
    2. Use that to prepare your vector
    3. Prompt the user for the vehicle details, in a loop

    Here's how it could look like:

    void addVehicle(std::vector<Vehicle>& vehicles){
        int vehiclesCount = 0;
        
        std::cout << "Please specify number of vehicles to add" << endl;
        std::cin >> vehiclesCount;
    
        // or some other validation logic for the vehiclesCount
        if (vehiclesCount <= 0) {
          return;
        }
    
        // pre-allocate memory all at once (only done if necessary)
        vehicles.reserve(vehiclesCount);
    
        for (int i = 0; i < vehiclesCount; ++i) {
          vehicle v;
          std::cout << "Please specify the vehicle model" << std::endl;
          std::cin >> v.model;
          std::cout << "Please specify the load capacity" << std::endl;
          std::cin >> v.capacity;
        
          vehicle.push_back(v);
        }
    }
    

    Then, you might also want to turn your classes with only public members into struct which will allow them to be aggregates, and distinguished as such:

    struct Silo {
        std::string name;
        int currentVolume;
        int storageVolume;
    };
    
    struct Vehicle {
        std::string model;
        int capacity;
    };
    

    You might also want to replace you C-style array with a C++ std::array. Since you classes into aggregate structs, you'll also benefit from the aggregate initialization syntax:

    std::array<Silo, 3> depoSilos = {
        {"Silo 1 - Aggregate", 1400,  40000},
        {"Silo 2 - Aggregate", 2300,  20000},
        {"Silo 3 - Aggregate", 11000,  40000}
    };
    

    To get the size of a container, you'll prefer using std::size or the dedicated member function:

    std::cout << "No. of available silos: " << std::size(depoSilos) << std::endl;
    
    for (int i = 0; i < std::size(depoSilos); ++i) {
    // [...]