3

让我的代码正常运行时遇到问题。它编译并显示我想要的,但是最后它崩溃了。我在想我没有在我的集合类中创建我的 items 数组的深层副本。下面是我的类实现以及我的驱动程序文件。任何帮助将不胜感激。

#ifndef COLLECTION_H
#define COLLECTION_H

#include <string>
#include <sstream>
#include <iostream>
using namespace std;

namespace VC {

    /*************************************************************************/
    /* Abstract class Vehicle.
     * This class serves as the superclass for all the concrete vehicles. It
     * provides the abstract method Type() that returns the type of each vehicle.
     */
    class Vehicle {
    private:
        string type;

    protected:
        /* Initializes the vehicle's type. It is protected,
         * so only child classes have access. The class is
         * abstract after all.
         */
        Vehicle(const string& type) { 
            this->type = type;
        } // end Vehicle()

    public:
        /* Returns the vehicle type. */
        string getType() const { 
            return type;
        } // end getType()

        /* No definition. Forces child class to implement, thus making
         * sure child can create a deep copy of itself.
         */
        virtual Vehicle* clone() const = 0;


        /* No definition. Child must implement. */
        virtual string toString() const =0;
    }; // end Vehicle
    /*************************************************************************/




    /* Concrete class Motorcycle.
     * This class defines a 'Motorcycle' type vehicle.
     */
    class Motorcycle : public Vehicle {
    private:
        int horsePowerInCc;

    public:
        // Initializes the horsepowerInCc and sets the type to "Motorcycle".
        Motorcycle(const int horsePowerInCc) :Vehicle("MotorCycle"){ 
            this->horsePowerInCc = horsePowerInCc;

        } // end Motorcycle()

        // Returns the horse power.
        int getHorsePowerInCc() const { 
            return horsePowerInCc;
        } // end getHorsePowerInCc

        // Sets the horse power.
        void setHorsePowerInCc(int horsePowerInCc) { 
            this->horsePowerInCc = horsePowerInCc;
        } // end setHorsePowerInCc

        // Returns a string with the type and CC power as:
        // <horsePowerInC><cc ><type>, i.e., 150cc Motorcycle.
        virtual string toString() const { 
            ostringstream oss;
            oss << horsePowerInCc << "cc " << getType() << "\n";
            return  oss.str();
        } // end toString()

        // Returns a deep copy of itself.
        virtual Motorcycle* clone() const { 
        return new Motorcycle(*this);
        } // end clone()
    }; // end Motorcycle

    /*************************************************************************/



    /* Concrete class Car.
     * This class defines a 'Car' type vehicle.
     */
    class Car : public Vehicle {
    private:
        int cylinders;

    public:
        // Initializes the cylinders with the parameter.
        // Sets the type to "Car".
        Car(const int cylinders) :Vehicle("Car"){ 
            this->cylinders = cylinders;

        } // end Car()


        // Returns the number of cylinders.
        int getCylinders() const { 
            return cylinders;
        } // end getCylinders

        // Sets the number of cylinders.
        void setCylinders(int cylinders) { 
            this->cylinders = cylinders;
        } // end setCylinders

        // Returns a string with the type and #of cylinders as:
        // <cylinders>< cylinder ><type>, i.e., 8 cylinder Car.
        virtual string toString() const { 
            ostringstream oss;
            oss << cylinders << " cylinder " << getType() << "\n";
            return  oss.str();
        } // end toString)

        // Returns a deep copy of itself.
        virtual Car* clone() const { 
            return new Car(*this);
        } // end clone()
    }; // end Car

    /*************************************************************************/




    /* Template class Collection.
     * This class serves as the template for our collection of objects. In
     * this version of the application, we are dealing with Vehicles.
     *
     * The template methods will be defined inline, thus avoiding the need for
     * an external implementation file, or the method implementations at the end
     * of this file.
     *
     * Inline means you simply add your implementation code inside each method
     * below. Also, make sure you turn this into a template right away.
     */

    template <typename T>
    class Collection {
    private:
        T* items[100];
        int numberOfItems;

        // Releases all the allocated memory to the heap.
        void releaseItems() { 
            for(int i = 0; i<100;i++){
                items[i] = NULL;
            }
            numberOfItems = 0;
        } // end releaseItems()

        // Clones all the items.
        void cloneItems(const Collection& cloneCollection) { 
            T* temp[100];



            for(int i = 0; i < 100; i++){
                temp[i] = NULL;
            }

            for(int i = 0; i < cloneCollection.count(); i++){

                temp[i] = cloneCollection.items[i];

            }

            for(int i = 0; i < cloneCollection.count(); i++){

                items[i] = temp[i];

            }

            numberOfItems = cloneCollection.count();




        } // end cloneItems()

    public:
        // Sets each element of the array to NULL, and numberOfItems to 0.
        Collection() {
            for(int i = 0; i<100;i++){
                items[i] = NULL;
            }
            numberOfItems = 0;
        } // end Collection()


        // Makes a deep copy of the parameter collection
        Collection(const Collection& cloneCollection) { 
            numberOfItems = cloneCollection.numberOfItems;
            cloneItems(cloneCollection);

        } // end Collection()


        /* Releases all the allocate memory to the heap. Sets each deleted
         * element to NULL.
         */
        virtual ~Collection() { 
            releaseItems();
        } // end ~Collection()


        /* Makes a clone of the parameter collection.
         */
        Collection operator =(const Collection& assignCollection) {  // end operator =()
            //if (this != &assignCollection) {
            releaseItems();
            numberOfItems = assignCollection.numberOfItems;
            cloneItems(assignCollection);
            return *this;
            //}
        }

        // Returns the numberOfItems in the collection.
        int count() const { 
            return numberOfItems;
        } // end count()


        /* If array is full, gives error message, does not add the object
         * and returns false. If not full, adds the object to the end of 
         * the array, increments numberOfItems and returns true.
         */
        bool add(T* object) { 
            if(numberOfItems == 100){
                cout<< "Array is full";
                return false;
            }else{
                items[numberOfItems] = object;
                numberOfItems++;
                return true;
            }
        } // end add()


        /* Removes the object at the specified index. If index is invalid,
         * gives an error message and returns false. If index is valid, then
         * deletes the object and moves the last element to fill the deleted
         * element, thus avoiding shifting of elements; it then decrements the
         * numberOfItems and returns true.
         */
        bool remove(const int index) { 
            if(index < 0 || index > numberOfItems -1){
                cout<<"Invalid index";
                return false;
            }else{
                for(int i = index; i < numberOfItems; i++){
                    items[i] = items[i+1];
                }
                return true;
            }
        } // end remove()


        /* If index is valid, returns reference to object. If index is invalid,
         * gives error message and returns NULL.
         */
        T* objectAt(const int index) const { 
            if(index < 0 || index > numberOfItems -1){
                cout<<"Invalid index";
                return NULL;
            }else{
                return items[index];
            }

        } // end objectAt()

        /* Returns the formatted collection of items. */
        string toString() const { 
            return "TEST-Collection";
        } // end toString()
    }; // end Collection

    /*************************************************************************/

} // end namespace
#endif

驱动文件:

#include "collection.h"
#include <iostream>

using namespace std;
using namespace VC;

int main() {
    Collection<Vehicle> vehicles;

    // Let's add a few vehicles to the collection.
    vehicles.add( new Motorcycle(150) );
    vehicles.add( new Car(4) );
    vehicles.add( new Car(6) );
    vehicles.add( new Motorcycle(200) );

    // Create another collection to test copy constructor and =().
    Collection<Vehicle> moreVehicles(vehicles);

    moreVehicles.add( new Car(8) );

//  // Display both collections.
//  // Now, let's display all the vehicles and their type.
    cout << "Original Collection: vehicles"
         << endl
         << "-----------------------------"
         << endl;
    for (int i = 0; i < vehicles.count(); i++) {
        cout << "item[" << i << "] = " << vehicles.objectAt(i)->toString();
    } // end for

    cout << endl << endl;
// Now, let's display all the vehicles and their type.
    cout << "Clone Collection: moreVehicles"
         << endl
         << "------------------------------"
         << endl;
    for (int i = 0; i < moreVehicles.count(); i++) {
        cout << "item[" << i << "] = " << moreVehicles.objectAt(i)->toString();
    } // end for

    cout << endl << endl;

    vehicles = moreVehicles;
    moreVehicles.remove(4);

    // Display both collections.
    // Now, let's display all the vehicles and their type.
    cout << "Assigned Collection: vehicles"
         << endl
         << "-----------------------------"
         << endl;
    for (int i = 0; i < vehicles.count(); i++) {
        cout << "item[" << i << "] = " << vehicles.objectAt(i)->toString();
    } // end for

    cout << endl << endl;

    // Now, let's display all the vehicles and their type.
    cout << "Adjusted Collection: moreVehicles"
         << endl
         << "---------------------------------"
         << endl;
    for (int i = 0; i < moreVehicles.count(); i++) {
        cout << "item[" << i << "] = " << moreVehicles.objectAt(i)->toString();
    } // end for

    cout << endl << endl;
    return (0);

} // end main()
4

0 回答 0