0

There are 3 types of planes.

  • A nA321 which has a max capacity of 10 containers
  • nB777 which has a max capacity of 32 containers
  • nB787 which has a max capacity of 40 containers

I want to index through the list and create an Airplane object and store the respective value. My for loop will create a new Airplane object that is set to 10. How can I dynamically set the respective plane types to the corresponding max capacity? The code currently outputs the address, for example:

Airplane 1 maximum load 0xffe

I am trying to print the following:

Airplane 1 maximum load 10
Airplane 2 maximum load 10
Airplane 3 maximum load 10
Airplane 4 maximum load 10
Airplane 5 maximum load 32
Airplane 6 maximum load 32
Airplane 7 maximum load 40

My code

#include <iostream>

using namespace std;

class Airplane
{
    public:
        Airplane(int n); // the maximum capacity of the airplane
        int maxLoad(void) const;
        int currentLoad(void) const;
        bool addContainers(int n);
    private:
        const int maxContainers;
        int numContainers;
};

Airplane::Airplane(int n):maxContainers(n){
    n = maxContainers;
}

int Airplane::maxLoad(void) const{
    return maxContainers;
}

int Airplane::currentLoad(void) const{
    return numContainers;
}

class Airline
{
    public:
        Airline(int nA321, int nB777, int nB787);
        ~Airline(void);
        void addShipment(int size);
        void printSummary(void) const; // prints a list of airplanes with their current and maximum load.
    
    private:
        const int nAirplanes; // total # of airplanes used by airline
        Airplane** airplaneList; // array of pointers to Airplane objects
};
  
Airline::Airline(int nA321, int nB777, int nB787):nAirplanes(nA321 + nB777 + nB787){
    airplaneList = new Airplane*[nAirplanes];
    for ( int i = 0; i < this->nAirplanes; i++ ){
        airplaneList[i] = new Airplane(10);
        airplaneList[i] -> maxLoad();
        cout << "Airline " << i+1 << " maximum load " << airplaneList[i] << endl;
    }
}

Airline::~Airline(void){}

int main(void)
{
    // create an Airline with 4 A321, 2 B777 and 1 B787
    Airline airline(4,2,1);
    cout << "Assignment complete" << endl;
}
user4581301
  • 33,082
  • 7
  • 33
  • 54
Alex
  • 3
  • 2
  • Use `cout ... airplaneList[i]->maxLoad();`. Explanation: `airplaneList` is a pointer to an array of `Airplane` pointers. So `airplaneList[i]` will be an `Airplane` pointer. So you need to dereference it, with `(*airplaneList[i]).maxLoad()` or `airplaneList[i]->maxLoad()`. Does it make sense? – rturrado Feb 11 '22 at 18:41
  • That makes sense! It is printing the value now, but how can I dynamically set the respective airplane type to the corresponding max capacity? I know I can set up 3 for loops, but doesn't seem like the cleanest approach – Alex Feb 11 '22 at 18:46
  • @Alex looks like 3 `for` loops IS a cleanesn approach in this case – Vlad Feinstein Feb 11 '22 at 18:51
  • 1
    Unrelated: [Avoid `new` as much as possible](https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new). If the option is available to you on this assignment, prefer to use a [`std::vector`](https://en.cppreference.com/w/cpp/container/vector) of [`std::unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr)s. You will have significantly fewer memory management woes. – user4581301 Feb 11 '22 at 19:24

1 Answers1

0

You can use runtime polymorphism:

  • Make your Airplane class virtual pure, so you cannot really instantiate an Airplane.
    virtual int maxLoad() const = 0;
  • Add 3 subclasses to your Airplane class, one for each type of plane. These subclasses will define the maximum number of containers, for example, using an static inline const member.
    static inline const int maxContainers{10};

  They will also implement the maxLoad virtual method to return maxContainers.

    virtual int maxLoad() const override { return maxContainers; }
  • For each airline, keep the airplaneList as an array of Airplane*, but then assign a specific plane instance to each of those pointers:
    airplaneList = new Airplane*[nAirplanes];
    int size = 0;
    for (int i = 0; i < nA321; i++, size++) { airplaneList[size] = new A321(); }
    for (int i = 0; i < nB777; i++, size++) { airplaneList[size] = new B777(); }
    for (int i = 0; i < nB787; i++, size++) { airplaneList[size] = new B787(); }
  • And two important points regarding destructors:
  1. Make Airplane destructor virtual.
     Since airplaneList is an array of Airplane pointers created through new, at some point we should do a delete of each of those pointers, and that is going to invoke the Airplane destructor; however, since we actually created instances of subclasses of Airplane (e.g. with new A321()), we need the destructor of the subclass to be executed.
     That won't be possible if the Airplane destructor is not virtual.
    virtual ~Airplane() {};
  1. Airline constructor is doing a new[] for the airplane list, and a new for each airplane. Airline destructor should do the correspondings delete[] and delete.
Airline::~Airline()
{
    for (int i = 0; i < nAirplanes; i++) { delete airplaneList[i]; }
    delete[] airplaneList;
}

[Demo]

// Outputs:
//
//   Airplane 1 (A321): maximum load = 10
//   Airplane 2 (A321): maximum load = 10
//   Airplane 3 (A321): maximum load = 10
//   Airplane 4 (A321): maximum load = 10
//   Airplane 5 (B777): maximum load = 32
//   Airplane 6 (B777): maximum load = 32
//   Airplane 7 (B787): maximum load = 40
//   Assignment complete

As an aside note, using a std::vector for the airplaneList, and smart pointers (e.g. std::unique_ptr) to the airplane instances would simplify the code a lot:

  • You wouldn't need the heap allocation for the airplane list.
  • You wouldn't need to care about deleting the heap instances for the airplanes and the airplane list.

[Demo]

class Airline
{
public:
    Airline(int nA321, int nB777, int nB787);
    ~Airline() {}
    void addShipment(int size);
    void printSummary(void) const; // prints a list of airplanes with their current and maximum load.

private:
    int nAirplanes{}; // total # of airplanes used by airline
    std::vector<std::unique_ptr<Airplane>> airplaneList{}; // array of pointers to Airplane objects
};
  
Airline::Airline(int nA321, int nB777, int nB787)
: nAirplanes(nA321 + nB777 + nB787)
{
    for (auto i = 0; i < nA321; i++) { airplaneList.emplace_back(std::make_unique<A321>()); }
    for (auto i = 0; i < nB777; i++) { airplaneList.emplace_back(std::make_unique<B777>()); }
    for (auto i = 0; i < nB787; i++) { airplaneList.emplace_back(std::make_unique<B787>()); }

    for (size_t i = 0; i < airplaneList.size(); i++)
    {
        std::cout
            << "Airplane " << i+1
            << " (" << airplaneList[i]->getName() << ")"
            << ": maximum load = " << airplaneList[i]->maxLoad() << "\n";
    }
}
rturrado
  • 7,699
  • 6
  • 42
  • 62