Complete the following task in C++. Separate your class into header and cpp files. You can only use iostream, string and sstream. Create a main.cpp file to test your code thoroughly.

commodity.h

#ifndef COMMODITY_H
#define COMMODITY_H
#include
#include
using namespace std;

class commodity
{
private:
   string name;
   int quantity;
public:
   commodity(commodity *c);
   commodity(string name,int quantity);
   ~commodity();
   string getName() const;
   int getQuantity() const;
};
#endif

commodity.cpp
#include “commodity.h”

commodity::commodity(commodity *c)
{
   this->name=c->getName();
   this->quantity=c->getQuantity();
}

commodity::commodity(string name,int quantity)
{
   this->name=name;
   this->quantity=quantity;
}

commodity::~commodity()
{
    cout

string commodity::getName() const
{
   return this->name;
}

int commodity::getQuantity() const
{
   return this->quantity;
}

locomotive.h

#ifndef LOCOMOTIVE_H
#define LOCOMOTIVE_H
#include
#include
#include “commodity.h”
using namespace std;

class locomotive
{
public:
   string name;
   double topSpeed;
   int maxCars;
   int tonLimit;
   commodity ** cars;

   locomotive();
   locomotive(string name, double topSpeed, int maxCars, int tonLimit);
   string getName();
   void setName(string s);
   double getTopSpeed() const;
   int getMaxCars() const;
   int getTonLimit() const;
   void setTopSpeed(double s);
   void setMaxCars(int s);
   void setTonLimit(int s);
   double getCurrentTopSpeed();
   void printManifest();
   int addCar(commodity *c);
   int removeCar(string s);
   void unassignCars();
   commodity * getFirstCar();
   int getCurrentTons();
   int getCurrentCars();
   ~locomotive();
   virtual string generateID()= 0;
   virtual double calculateRange();
   virtual string getType();

};

#include “locomotive.h”
locomotive::locomotive()
{

}

locomotive::locomotive(string name, double topSpeed, int maxCars, int tonLimit)
{
   this->name = name;
   this->topSpeed = topSpeed;
   this->maxCars = maxCars;
   this->tonLimit = tonLimit;
   this->cars = new commodity *[maxCars];
   for (int i = 0; i
       this->cars[i] = NULL;
}

locomotive::~locomotive()
{
   for (int i = 0; i < this->maxCars; i++)
   {
       if (this->cars[i] != NULL)
       {
           commodity * tmp = this->cars[i];
           this->cars[i] = NULL;
       }
   }

}

string locomotive::getName() const
{
   return this->name;
}

void locomotive::setName(string s)
{
   this->name = s;
}

double locomotive::getTopSpeed() const
{
   return this->topSpeed;
}

int locomotive::getMaxCars() const
{
   return this->maxCars;
}

int locomotive::getTonLimit() const
{
   return this->tonLimit;
}

void locomotive::setTonLimit(int s)
{
   this->tonLimit = s;
}

void locomotive::setTopSpeed(double s)
{
   this->topSpeed = s;
}

void locomotive::setMaxCars(int s)
{
   this->maxCars = s;
   if (this->cars == NULL)
   {

       this->cars = new commodity *[maxCars];
       for (int i = 0; i
           this->cars[i] = NULL;
   }
}

int locomotive::getCurrentTons()
{
   int total_ton=0;
   for (int i = 0; i < this->maxCars; i++)
   {
       if (this->cars[i] != NULL)
       {
           total_ton += this->cars[i]->getQuantity();
       }
   }
   return total_ton;
}

int locomotive::getCurrentCars()
{
   int total_car = 0;
   for (int i = 0; i < this->maxCars; i++)
   {
       if (this->cars[i] != NULL)
       {
           total_car ++;
       }
   }
   return total_car;
}

commodity *locomotive :: getFirstCar()
{
   for (int i = 0; i < this->maxCars; i++)
   {
       if (this->cars[i] != NULL)
       {
           return this->cars[i];
       }
   }
   return NULL;
}

double locomotive::calculateRange()
{
   // specific to subclass
   return 0.0;
}

int locomotive::addCar(commodity *c)
{
   int i;
   if (getCurrentTons() + c->getQuantity() > getTonLimit()) return -1;
       for (i = 0; i < this->maxCars; i++)
       {
           if (this->cars[i] == NULL)
           {
               this->cars[i] = c;
               break;
           }
       }
       if (i == this->maxCars) return -1;
       return i;

}

int locomotive::removeCar(string s)
{
   int flag = -1;
   for (int i = 0; i < this->maxCars; i++)
   {
       if (this->cars[i] != NULL)
       {
           if (this->cars[i]->getName() == s)
           {
               commodity * tmp = this->cars[i];
               this->cars[i] = NULL;
        
               flag = i;
               break;
           }
       }
   }
   return flag;
}

void locomotive::unassignCars()
{
   for (int i = 0; i < this->maxCars; i++)
   {
       if (this->cars[i] != NULL)
       {
               commodity * tmp = this->cars[i];
               this->cars[i] = NULL;
            
       }
   }
}

void locomotive:: printManifest()
{
   int count=1;
   cout << "Train: " << this->name
   for (int i = 0; i < this->maxCars; i++)
   {
       if (this->cars[i] != NULL)
       {
           cout << "Car " << count << ": " << this->cars[i]->getName()
           count++;
       }
   }
   cout
}

double locomotive::getCurrentTopSpeed()
{
   double current_speed = (getTopSpeed() – (1.7*getCurrentCars() – (1.01*(getCurrentTons() / 10.0))));
   if (getCurrentTons() > getTonLimit() || current_speed
       return 0.0;
   return current_speed;
}

string locomotive::getType()
{
   return ” “;
} Locomotive Class Hierarchy Presented here will be a class diagram depicting the nature of the class hierarchy formed hctwccn a parcnt locomotive class and its children, the two kinds of specific trains operated. The relationship is a strict one to many relationship with eacli specific class of locomotive being a direct descendent of the locomotive class. The inheritance type is public in all cases. This is presented in Figure 1: Locomotive -name: string -topSpeed: double -TlaxCars.int -Ion Limit: int -cars: commodity ** generateID()-0. string +calculateRange(): double DieselElectric DieselElectric Steam Steam Figure 1: A UML Class diagram showing the class hierarchy As demonstrated, the locomotive class is the parent class which the other 2 are descended from. In particular it is also an abstract class, having a pure virtual function and is not intended to be instantiated. Note that only salient features are captured in the above class diagram. For full specifics on each of the classes, refer below. The class specifics of the subclasses are discussed below with a UML specification and details about what specific behaviour, functions and operators each class needs to implement. get Type: This function returns the type of the locomotive as a string. The base class type should be set to locomotive. It is virtual and the children should override it to return dieselElectric and steam respectively. DieselElectric dieselElectric -fuelSupply:int +get Supply :int +sot Supply(s:int):void +dieselElectric(f:int) +”dieselElectric +generateID :string +calculateRange():double The class variables are as follows: • fuelSuppply: The fuel supply of the train in terms of a number of kilolitres of diesel fucl. The class methods are als follows: • Getter and Setter: The getter and setter for the sundry class variable. • dieselElectric(f:int): The constructor for the class. It should instantiate the class based on the given parameters. • dieselElectrici): The destructor for the class. It should deallocate any meinory assigned to the class. Additionally, it should (as the first thing it does) print Diesel Electric Train: ” with a newline at the end. ” in this case refers to the traill&#39;s ID generated with its function. generateIDO: This function generates a unique ID for the train by producing a string that has the following structure: – The start of the string is the type of train. – Append the first 3 letters from the first commodity – Append the total tonnage carried by the train to the end Each should be separated by a “_” So for example, dieselElectric-Coa-1000 You can assume there will be at least one commodity when this function is called. • calculateRange(): This calculates and returns the range of the train using the fol- lowing equation: Range=(fuelSupply *3.5)- 5*(avgTonsPerCar) If the range is negative, then the range should be set to 0. The average tons per car only considers the current number of cars and tons associated with those cars. Steain steam -coal:int -water:int +getWater):int +setWater(s:int):void +getCoal:int +setCoal(s:int):void +steam(c:int,w:int) + steam) +generateID :string +calculateRange :double The class variables are as follows: • coal: The coal supply of the train in terms of a number of kgs of coal carried in an included car. water: The water supply of the train in terms of a number of litres of water carried in an included car. The class methods are as follows: • Getter and Setter: The getter and setter for the class variables. steam(c:int.w:int): The constructor for the class. It should instantiate the class based on the given parameters. . steam(): The destructor for the class. It should deallocate any memory assigned to the class. Additionally, it should (as the first thing it does) print “Steam Train: ” with a newline at the end. ” in this case refers to the train&#39;s ID generated with its function. • generateID(): This function generates a unique ID for the train by producing a string that has the following structure: – The start of the string is the type of trairi. – Append the first 3 letters from the first commodity – Append the total tonnage carried by the train to the end Each should be separated by “-” So for example, steam-Lum-250 You can assume there will be at least onc commodity when this function is called. • calculateRange(): This calculates the range of the train using the following process: 1. 2 kgs of coal and 1 litre of water equals to 2km. 2. Calculate the base range by computing the total range through determining how many kms are available given the above ratio of coal to water to km. So if 10 kgs of coal and 5 litres of water are available, then the train has a base range of 5km. You should ignore uneven quantities. Only coal and water that meets the minimum ratio requirement should be considered. 3. Subtract from this base range, 1.2 * number of cars 4. Return the final range value I “S If the range is negative, then the range should be set to 0.

"Get 15% discount on your first 3 orders with us"
Use the following coupon
"FIRST15"

Order Now