首页 > 解决方案 > 覆盖打印功能不覆盖基类

问题描述

我试图让我的代码显示 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;

    }

标签: c++overridingoperators

解决方案


对于初学者,这些数据成员

    int yearBuilt;
    string nameOfShip;

应该保护访问说明符而不是公共的。

在这个构造函数中

    Ship(int year, string name) {

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

        year = 0;
        name = "";
    }

最后两个语句是多余的,没有意义。像这样定义构造函数

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

最好定义这些 getter

    // 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]);

推荐阅读