コードを正しく実行するのに問題があります。それは私が望むものをコンパイルして表示しますが、最終的にクラッシュします。コレクション クラスでアイテム配列のディープ コピーを作成していないと考えています。以下は、私のクラスの実装とドライバー ファイルです。どんな助けでも大歓迎です。
#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()