Переопределение функции печати не отменяет базовый класс - PullRequest
0 голосов
/ 17 июня 2020

Я пытаюсь получить свой код для отображения данных класса Ship, а затем использовать указатели для отображения обновленных данных после ввода в консоль и установки соответствующих переменных в классах CruiseShip и CragoShip. Однако программа проигнорирует любой новый ввод и просто снова отобразит данные базового класса независимо от новых данных.

Чего здесь не хватает?


    using namespace std;

    // -- Initialized the class 'Ship' -- //

    class Ship {

    public:

        int yearBuilt;
        string nameOfShip;

        // Constructs the ship class and defines the values of the variables
        Ship() {
            yearBuilt = 0;
            nameOfShip = "";
        }
        // Overloaded Constructor
        Ship(int year, string name) {

            Ship::yearBuilt = year;
            Ship::nameOfShip = name;

            year = 0;
            name = "";
        }
        // Accessor Function for the year the ship was built
        int getYearBuilt() const {
            return yearBuilt;
        }
        // Accessor Function for the name of the ship
        string getShipName() const {
            return nameOfShip;
        }
        // Mutator Function to read input and set it to the value of yearBuilt
        void setShipYear(int year) {
            cout << " Enter Year: " << endl;
            cin >> year;
            year = yearBuilt;

            cout << endl; // Spacing between printed data
        }
        // Mutator Function to read input and set it to the value of nameOfShip
        void setShipName(string name) {
            cout << " Enter Name: " << endl;
            cin >> name;
            name = nameOfShip;

            cout << endl; // Spacing between printed data
        }
        // Virtual Print function to display the name of the ship and the year it was built
        virtual void print() const {

            cout << " Ship Name: " << nameOfShip << endl;
            cout << " Year Built: " << yearBuilt << endl;
        }
    };

    // -- Initializes the class 'CruiseShip' derived from Ship class -- //

    class CruiseShip : public Ship
    {

    // Set the member variable for max number of passengers

    int passengersMAX;

    public:

        //Constructor for CruiseShip, calls parent class

        CruiseShip() : Ship() {

            passengersMAX = 0;
        }

        //Overloaded Constructor
        CruiseShip(int maximum, int year, string name) : Ship() {
            CruiseShip::passengersMAX = maximum;
        }

        //Accessor
        int getMaxPass() const {
            return passengersMAX;
        }

        //Mutator
        void setMaxPass(int maximum) {
            cout << "Enter Passenger Max: " << endl;
            cin >> maximum;
            maximum = passengersMAX;
        }

        //Overriding Print Function
        virtual void print() const override{
            cout << " Ship Name: " << nameOfShip << endl;
            cout << " Max number Of Passengers: " << passengersMAX << endl;
        }
    };

    class CargoShip : public Ship
    {

    // Set the member variable for tonnage / capacity

    int capacity;

    public:

        // Default Constructor

        CargoShip() : Ship() {
            capacity = 0;
        }

        //Overloaded constructor for CargoShip, calls parent class

        CargoShip(int tonnage, string name) : Ship() {

            CargoShip::capacity = tonnage;
        }

        // Accessor Function 
        int getCapacity() const {
            return capacity;
        }

        //Mutator Function
        void setCapacity(int tonnage) {
            cout << " Enter max capacity: " << endl;
            cin >> tonnage;
            tonnage = capacity;
        }

        //Overriding Print Function
        virtual void print() const override{
            cout << " Name: " << nameOfShip << endl;
            cout << " Capacity: " << capacity << endl;
        }
    };


    int main()
    {

        // Pointer Array for Ships, listing the 3 ship classes

        Ship *shipArray[3] = { new Ship(), new CruiseShip(), new CargoShip() };


        // For loop to print the data for each of the 3 ships
        for (int i = 0; i < 3; i++) 
        {
            shipArray[i]->print();
            cout << endl;
        }

        // Stores new data using the mutator functions within the class
        shipArray[0]->setShipName("RMS Titanic");
        shipArray[0]->setShipYear(1909); 

        // Pointers to the derived class, stores new data for functions in CruiseShip class
        CruiseShip *csPoint = static_cast<CruiseShip*>(shipArray[1]);
        csPoint->setShipName("HMS Victory");
        csPoint->setMaxPass(850);

        // Pointer to the derived class, stores new data for functions in CargoShip class
        CargoShip *cgPoint = static_cast<CargoShip*>(shipArray[2]);
        cgPoint->setShipName("HMHS Britannic");
        cgPoint->setCapacity(48158);

        //For loop to re-display updated data using base class pointers
        for (int i = 0; i < 3; i++) {
            shipArray[i]->print();
            cout << endl;
        }

        return 0;

    }

1 Ответ

0 голосов
/ 17 июня 2020

Для начала, эти элементы данных

    int yearBuilt;
    string nameOfShip;

должны иметь защищенный спецификатор доступа вместо publi c.

В этом конструкторе

    Ship(int year, string name) {

        Ship::yearBuilt = year;
        Ship::nameOfShip = name;

        year = 0;
        name = "";
    }

последний два утверждения избыточны и не имеют смысла. Определите конструктор, например,

    Ship( int year, const string &name ) : yearBuilt( year ), nameOfShip( name )
    {
    }

. Лучше определить эти геттеры

    // Accessor Function for the year the ship was built
    int getYearBuilt() const {
        return yearBuilt;
    }
    // Accessor Function for the name of the ship
    string getShipName() const {
        return nameOfShip;
    }

как

    // Accessor Function for the year the ship was built
    const int & getYearBuilt() const {
        return yearBuilt;
    }
    // Accessor Function for the name of the ship
    const string & getShipName() const {
        return nameOfShip;
    }

Эти сеттеры не имеют смысла. Например, аргументы не используются. Более того, вы пытаетесь переназначить аргументы с элементами данных.

    // Mutator Function to read input and set it to the value of yearBuilt
    void setShipYear(int year) {
        cout << " Enter Year: " << endl;
        cin >> year;
        year = yearBuilt;

        cout << endl; // Spacing between printed data
    }
    // Mutator Function to read input and set it to the value of nameOfShip
    void setShipName(string name) {
        cout << " Enter Name: " << endl;
        cin >> name;
        name = nameOfShip;

        cout << endl; // Spacing between printed data
    }

они должны быть определены как минимум как

    // Mutator Function to read input and set it to the value of yearBuilt
    void setShipYear(int year) {
        yearBuilt = year;
    }
    // Mutator Function to read input and set it to the value of nameOfShip
    void setShipName(string name) {
        nameOfShip - name;
    }

Этот конструктор

    //Overloaded Constructor
    CruiseShip(int maximum, int year, string name) : Ship() {
        CruiseShip::passengersMAX = maximum;
    }

не инициализировать элементы данных базового класса переданными аргументами. Он должен быть определен как

    //Overloaded Constructor
    CruiseShip(int maximum, int year, const string &name) : Ship(year, name ), passengersMAX( maximum )
    {
    }

Этот установщик

    //Mutator
    void setMaxPass(int maximum) {
        cout << "Enter Passenger Max: " << endl;
        cin >> maximum;
        maximum = passengersMAX;
    }

должен быть определен как

    //Mutator
    void setMaxPass(int maximum) {
        passengersMAX = maximum;
    }

Этот конструктор

    CargoShip(int tonnage, string name) : Ship() {

        CargoShip::capacity = tonnage;
    }

делает не инициализировать с аргументом подобъект базового класса. Более того, член данных yearBuilt не имеет соответствующего аргумента.

Таким образом, по крайней мере, конструктор должен быть определен как

    CargoShip(int tonnage, string name) : Ship( 0, name ), capacity( tonnage )
    {
    }

Этот метод установки

   //Mutator Function
    void setCapacity(int tonnage) {
        cout << " Enter max capacity: " << endl;
        cin >> tonnage;
        tonnage = capacity;
    }

должен быть определен например,

   //Mutator Function
    void setCapacity(int tonnage) {
        capacity = tonnage;
    }

В этом объявлении

    CruiseShip *csPoint = static_cast<CruiseShip*>(shipArray[1]);
    //...
    CargoShip *cgPoint = static_cast<CargoShip*>(shipArray[2]);

вы должны использовать reinterpret_cast

    CruiseShip *csPoint = reinterpret_cast<CruiseShip*>(shipArray[1]);
    //...
    CargoShip *cgPoint = reinterpret_cast<CargoShip*>(shipArray[2]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...