How do I add exception-handling to this code and make sure it compiles and runs properly?

R

robinsand

Header File: car.h #if !defined CAR_H
#define CAR_H

enum TCarType { ctEconomy = 1, ctCompact, ctStandard, ctFullSize,
ctMiniVan, ctSUV };

class Car
{
public:
Car();
Car(char *MM, int Y, int Cat);
virtual ~Car();
void setMakeModel(const char *mm);
char* getMakeModel() const;
void setCarYear(const int y);
int getCarYear() const;
void setCategory(const int c);
int getCategory() const;

private:
char* MakeModel;
int CarYear;
int Category;
};

#endif // CAR_H



Source File: car.cpp // Car.cpp: implementation of the Car class.

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

#include "Car.h"

//--------------------------------------------------------------------
Car::Car()
{
setMakeModel("No Car Selected");
setCarYear(2000);
setCategory(1);
}
//--------------------------------------------------------------------
Car::Car(char *MM, int Y, int Cat)
{
setMakeModel(MM);
setCarYear(Y);
setCategory(Cat);
}
//--------------------------------------------------------------------
Car::~Car()
{
// delete [] MakeModel;
}
//--------------------------------------------------------------------
void Car::setMakeModel(const char *m)
{
MakeModel = new char[strlen(m) + 1];
strcpy(MakeModel, m);
}
//--------------------------------------------------------------------
char* Car::getMakeModel() const
{
return MakeModel;
}
//--------------------------------------------------------------------
void Car::setCarYear(const int y)
{
CarYear = y;
}
//--------------------------------------------------------------------
int Car::getCarYear() const
{
return CarYear;
}
//--------------------------------------------------------------------
void Car::setCategory(const int c)
{
Category = c;
}
//--------------------------------------------------------------------
int Car::getCategory() const
{
return Category;
}
//--------------------------------------------------------------------



Header File: customer.h #if !defined CUSTOMER_H
#define CUSTOMER_H

class Customer
{
private:
char* FirstName;
char* LastName;
char* Address;
char* City;
char* State;
long ZIPCode;

public:
void setFirstName(const char *FN);
char* getFirstName() const { return FirstName; }
void setLastName(const char *LN);
char* getLastName() const { return LastName; }
char* FullName() const;
void setAddress(const char *Adr);
char* getAddress() const { return Address; }
void setCity(const char *CT);
char* getCity() const { return City; }
void setState(const char *St);
char* getState() const { return State; }
void setZIPCode(const long ZIP);
long getZIPCode() const { return ZIPCode; }
Customer();
Customer(char *FName, char *LName, char *Adr,
char *Ct, char *St, long ZIP);
Customer(const Customer &Pers);
Customer(char * FName, char * LName);
~Customer();
};

#endif // CUSTOMER_H



Source File: customer.cpp
//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
#pragma hdrstop

#include "Customer.h"

//---------------------------------------------------------------------------
char *Customer::FullName() const
{
char *FName = new char[40];
strcpy(FName, FirstName);
strcat(FName, " ");
strcat(FName, LastName);

return FName;
}
//---------------------------------------------------------------------------
Customer::Customer()
: ZIPCode(0)
{
FirstName = new char[20];
strcpy(FirstName, "John");
LastName = new char[20];
strcpy(LastName, "Doe");
Address = new char[40];
strcpy(Address, "123 Main Street Apt A");
City = new char[32];
strcpy(City, "Great City");
State = new char[30];
strcpy(State, "Our State");
}
//---------------------------------------------------------------------------
Customer::Customer(char * FName, char * LName)
: ZIPCode(0)
{
FirstName = new char[strlen(FName) + 1];
strcpy(FirstName, FName);
LastName = new char[strlen(LName) + 1];
strcpy(LastName, LName);
Address = new char[40];
strcpy(Address, "123 Main Street Apt A");
City = new char[32];
strcpy(City, "Great City");
State = new char[30];
strcpy(State, "Our State");
}
//---------------------------------------------------------------------------
Customer::Customer(char *FName, char *LName, char *Adr,
char *Ct, char *St, long ZIP)
: ZIPCode(ZIP)
{
FirstName = new char[strlen(FName) + 1];
strcpy(FirstName, FName);
LastName = new char[strlen(LName) + 1];
strcpy(LastName, LName);
Address = new char[40];
strcpy(Address, Adr);
City = new char[32];
strcpy(City, Ct);
State = new char[30];
strcpy(State, St);
}
//---------------------------------------------------------------------------
Customer::Customer(const Customer &Pers)
: ZIPCode(Pers.ZIPCode)
{
FirstName = new char[strlen(Pers.FirstName) + 1];
strcpy(FirstName, Pers.FirstName);
LastName = new char[strlen(Pers.LastName) + 1];
strcpy(LastName, Pers.LastName);
Address = new char[strlen(Pers.Address) + 1];
strcpy(Address, Pers.Address);
City = new char[strlen(Pers.City) + 1];
strcpy(City, Pers.City);
State = new char[strlen(Pers.State) + 1];
strcpy(State, Pers.State);
}
//---------------------------------------------------------------------------
void Customer::setFirstName(const char *FN)
{
strcpy(FirstName, FN);
}
//---------------------------------------------------------------------------
void Customer::setLastName(const char *LN)
{
strcpy(LastName, LN);
}
//---------------------------------------------------------------------------
void Customer::setAddress(const char *Adr)
{
strcpy(Address, Adr);
}
//---------------------------------------------------------------------------
void Customer::setCity(const char *CT)
{
strcpy(City, CT);
}
//---------------------------------------------------------------------------
void Customer::setState(const char *St)
{
strcpy(State, St);
}
//---------------------------------------------------------------------------
void Customer::setZIPCode(const long ZIP)
{
ZIPCode = ZIP;
}
//---------------------------------------------------------------------------
Customer::~Customer()
{
delete [] FirstName;
delete [] LastName;
delete [] Address;
delete [] City;
delete [] State;
}
//---------------------------------------------------------------------------



Header File: Invoice.h

#if !defined INVOICE_H
#define INVOICE_H

#include "Customer.h"
#include "Car.h"
#include "RentDate.h"

class Invoice
{
public:
Invoice();
virtual ~Invoice();
Customer CustomerRegistration();
void CustomerInformation(const Customer& Pers);
Car CarSelection();
void CarSelected(const Car& Vehicle);
double CalculatePrice(const Car& Vehicle, double& Rate, int &Days);
void setMileage(const long g);
long getMileage() const;
void setTankLevel(const char *v);
char* getTankLevel() const;
void setCarCondition(const char *c);
char* getCarCondition() const;

void ProcessOrder();
void CarExamination();
void ShowOrder();

private:
long Mileage;
char *TankLevel;
char *CarCondition;
};

#endif // INVOICE_H


Source File: Invoice.cpp

// Invoice.cpp: implementation of the Invoice class.
//
//////////////////////////////////////////////////////////////////////
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

#include "Invoice.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Invoice::Invoice()
{
setTankLevel("Empty");
setCarCondition("Good");
}
//--------------------------------------------------------------------
Invoice::~Invoice()
{
}
//--------------------------------------------------------------------
Customer Invoice::CustomerRegistration()
{
char FName[20], LName[20], Addr[40], CT[32], St[30];
long ZC = 0;

cout << "Enter Customer Information\n";
cout << "First Name: "; cin >> FName;
cout << "Last Name: "; cin >> LName;
cout << "Address: "; cin >> ws;
cin.getline(Addr, 40);
cout << "City: ";
cin.getline(CT, 32);
cout << "State: ";
cin.getline(St, 30);
cout << "Zip Code: "; cin >> ZC;

Customer Cust(FName, LName, Addr, CT, St, ZC);
return Cust;
}
//--------------------------------------------------------------------
Car Invoice::CarSelection()
{
int CarType, ModelChosen;
char strCarSelected[20];
int CarSelectedYear = 2000;

cout << "What type of car would you like to rent?";
do {
cout << "\n1 - Economy | 2 - Compact | 3 - Standard"
<< "\n4 - Full Size | 5 - Mini Van | 6 - Sports Utility";
cout << "\nYour Choice: ";
cin >> CarType;
if( CarType < 1 || CarType > 6 )
cout << "\nPlease type a number between 1 and 6";
} while(CarType < 1 || CarType > 6);

switch(CarType)
{
case ctEconomy:
cout << "\nFor the Economy type, we have:"
<< "\n1 - Daewoo Lanos | 2 - Cheverolet Metro";
cout << "\nWhich one would you prefer? ";
cin >> ModelChosen;

if(ModelChosen == 1)
{
strcpy(strCarSelected, "Daewoo Lanos");
CarSelectedYear = 1999;
}
else
{
strcpy(strCarSelected, "Chevrolet Metro");
CarSelectedYear = 1998;
}
break;

case ctCompact:
cout << "\nFor the Compact type, we have:"
<< "\n1 - Chevrolet Cavalier | 2 - Dogde Neon"
<< "\n3 - Nissan Sentra | 4 - Toyota Corolla";
cout << "\nWhich one would you prefer? ";
cin >> ModelChosen;

if(ModelChosen == 1)
{
strcpy(strCarSelected, "Chevrolet Cavalier");
CarSelectedYear = 1999;
}
else if(ModelChosen == 2)
{
strcpy(strCarSelected, "Dodge Neon");
CarSelectedYear = 2001;
}
else if(ModelChosen == 3)
{
strcpy(strCarSelected, "Nissan Sentra");
CarSelectedYear = 1998;
}
else
{
strcpy(strCarSelected, "Toyota Corrolla");
CarSelectedYear = 2002;
}
break;

case ctStandard:
cout << "\nFor the Standard type, we have:"
<< "\n1 - Chevrolet Monte Carlo | 2 - Toyota Camri";
cout << "\nWhich one would you prefer? ";
cin >> ModelChosen;

if(ModelChosen == 1)
{
strcpy(strCarSelected, "Chevrolet Monte Carlo");
CarSelectedYear = 2000;
}
else
{
strcpy(strCarSelected, "Toyota Camri");
CarSelectedYear = 1998;
}
break;

case ctFullSize:
cout << "\nFor the Full Size type, we have:"
<< "\n1 - Chrysler 300M | 2 - Buick Century | 3 - Infinity I30";
cout << "\nWhich one would you prefer? ";
cin >> ModelChosen;

if(ModelChosen == 1)
{
strcpy(strCarSelected, "Chrysler 300M");
CarSelectedYear = 2000;
}
else if(ModelChosen == 2)
{
strcpy(strCarSelected, "Buick Century");
CarSelectedYear = 1999;
}
else
{
strcpy(strCarSelected, "Infinity I30");
CarSelectedYear = 2003;
}
break;

case ctMiniVan:
cout << "\nFor the Mini-Van type, we have:"
<< "\n1 - Dodge Caravan | 2 - Dodge Caravan"
<< "\n3 - Pontiac Montana | 4 - Pontiac Montana | 5 - Chevrolet
Astro Van";
cout << "\nWhich one would you prefer? ";
cin >> ModelChosen;

if(ModelChosen == 1)
{
strcpy(strCarSelected, "Dodge Caravan");
CarSelectedYear = 2001;
}
else if(ModelChosen == 2)
{
strcpy(strCarSelected, "Dodge Caravan");
CarSelectedYear = 2003;
}
else if(ModelChosen == 3)
{
strcpy(strCarSelected, "Pontiac Montana");
CarSelectedYear = 2003;
}
else
{
strcpy(strCarSelected, "Chevrolet Astro Van");
CarSelectedYear = 2000;
}
break;

case ctSUV:
cout << "\nFor the Sport Utility type, we have:"
<< "\n1 - GMC Jimmy | 2 - Jeep Cherokee"
<< "\n3 - Chevrolet Blazer | 4 - Toyota Pathfinder";
cout << "\nWhich one would you prefer? ";
cin >> ModelChosen;

if(ModelChosen == 1)
{
strcpy(strCarSelected, "GMC Jimmy");
CarSelectedYear = 1998;
}
else if(ModelChosen == 2)
{
strcpy(strCarSelected, "Jeep Cherokee");
CarSelectedYear = 2003;
}
else if(ModelChosen == 3)
{
strcpy(strCarSelected, "Chevrolet Blazer");
CarSelectedYear = 2001;
}
else
{
strcpy(strCarSelected, "Toyota Pathfinder");
CarSelectedYear = 2000;
}
break;
}

Car Selected(strCarSelected, CarSelectedYear, CarType);
return Selected;
}
//--------------------------------------------------------------------
void Invoice::setMileage(const long g)
{
Mileage = g;
}
//--------------------------------------------------------------------
long Invoice::getMileage() const
{
return Mileage;
}
//--------------------------------------------------------------------
void Invoice::setTankLevel(const char *v)
{
TankLevel = new char[strlen(v) + 1];
strcpy(TankLevel, v);
}
//--------------------------------------------------------------------
char* Invoice::getTankLevel() const
{
return TankLevel;
}
//--------------------------------------------------------------------
void Invoice::setCarCondition(const char *c)
{
CarCondition = new char[strlen(c) + 1];
strcpy(CarCondition, c);
}
//--------------------------------------------------------------------
char* Invoice::getCarCondition() const
{
return CarCondition;
}
//--------------------------------------------------------------------
void Invoice::processOrder()
{
int NbrOfDays;;
double Rate, TotalPrice;
// Enter Customer Information
Customer Person = CustomerRegistration();
cout << "\nProcess Car Information\n";
Car Driving = CarSelection();

TotalPrice = CalculatePrice(Driving, Rate, NbrOfDays);
CarExamination();

// This function works for both Borland C++ Builder and MSVC
system("cls");

cout << " - Bethesda Car Rental -";
cout << "\n=============================";
CustomerInformation(Person);
cout << "\n------------------------------";
CarSelected(Driving);
cout << setiosflags(ios::fixed) << setprecision(2);
cout << "\n------------------------------";
cout << "\nCar Mileage: " << getMileage();
cout << "\nCondition: " << getCarCondition();
cout << "\nTank Level: " << getTankLevel();
cout << "\n# of Days: " << NbrOfDays;
cout << "\n------------------------------";
cout << "\nRate: $" << Rate;
cout << "\nTotal Price: $" << TotalPrice;
cout << "\n==============================\n";
}
//--------------------------------------------------------------------
void Invoice::CustomerInformation(const Customer& Pers)
{
cout << "\nEmployee Identification";
cout << "\nFull Name: " << Pers.FullName();
cout << "\nAddress: " << Pers.getAddress();
cout << "\nCity: " << Pers.getCity() << ", "
<< Pers.getState() << " " << Pers.getZIPCode();
}
//--------------------------------------------------------------------
void Invoice::CarSelected(const Car& Vehicle)
{
cout << "\nModel: " << Vehicle.getMakeModel();
cout << "\nYear: " << Vehicle.getCarYear();
}

//--------------------------------------------------------------------
double Invoice::CalculatePrice(const Car& Vehicle, double& DayRate,
int &NumberOfDays)
{
// char WeekEndResponse;// Does the customer rent the car for the
week-end?
double OneDayRate, // If renting for less than 5 days including
week-end
WeekDay, // If renting for at least 5 days, regardless of the days
WeekEnd = 0;// If renting for more than two days from Friday to
monday
//double DayRate; // Rate applied based on the number of days
double TotalRate;

switch(Vehicle.getCategory())
{
case ctEconomy:
DayRate = 24.95;
OneDayRate = 29.95;
WeekDay = 24.95;
WeekEnd = 19.95;
break;

case ctCompact:
DayRate = 34.95;
OneDayRate = 39.95;
WeekDay = 34.95;
WeekEnd = 25.95;
break;

case ctStandard:
DayRate = 38.95;
OneDayRate = 49.95;
WeekDay = 38.95;
WeekEnd = 32.95;
break;

case ctFullSize:
DayRate = 44.95;
OneDayRate = 69.95;
WeekDay = 44.95;
WeekEnd = 35.95;
break;

case ctMiniVan:
DayRate = 54.95;
OneDayRate = 89.95;
WeekDay = 54.95;
WeekEnd = 42.95;
break;

case ctSUV:
DayRate = 64.95;
OneDayRate = 89.95;
WeekDay = 64.95;
WeekEnd = 50.95;
break;
}

cout << "\nHow many days? "; cin >> NumberOfDays;
TotalRate = DayRate * NumberOfDays;
return TotalRate;
}
//--------------------------------------------------------------------
void Invoice::CarExamination()
{
char Cond;
int GasLevel;

cout << "Rate the car's condition (e=Excellent/g=Good/d=Driveable): ";
cin >> Cond;
if( Cond == 'e' || Cond == 'E' )
strcpy(CarCondition, "Excellent");
else if( Cond == 'g' || Cond == 'G' )
strcpy(CarCondition, "Good");
else if( Cond == 'd' || Cond == 'D' )
strcpy(CarCondition, "Driveable");
else
strcpy(CarCondition, "Can't Decide");

cout << "Enter the car mileage: ";
cin >> Mileage;

do {
cout << "Gas level in the tank"
<< "\n1 - Considered Empty"
<< "\n2 - 1/4 Full"
<< "\n3 - Half Full"
<< "\n4 - 3/4 Full"
<< "\n5 - Full Tank";
cout << "\nEnter the gas level: ";
cin >> GasLevel;
}while(GasLevel < 1 || GasLevel > 5);

switch(GasLevel)
{
case 1:
setTankLevel("Empty");
break;
case 2:
setTankLevel("1/4 Full");
break;
case 3:
setTankLevel("Half Full");
break;
case 4:
setTankLevel("3/4 Full");
break;
case 5:
setTankLevel("Full Tank");
break;
}
}
//--------------------------------------------------------------------


Main File: Main.cpp

#include "Invoice.h"

void main()
{
CInvoice Order;

Order.ProcessOrder();
Order.ShowOrder();
}
 
A

Alf P. Steinbach

* (e-mail address removed):
Header File: car.h #if !defined CAR_H
#define CAR_H

enum TCarType { ctEconomy = 1, ctCompact, ctStandard, ctFullSize,
ctMiniVan, ctSUV };

class Car
{
public:
Car();
Car(char *MM, int Y, int Cat);
virtual ~Car();
void setMakeModel(const char *mm);
char* getMakeModel() const;
void setCarYear(const int y);
int getCarYear() const;
void setCategory(const int c);
int getCategory() const;

private:
char* MakeModel;
int CarYear;
int Category;
};

Except for the constructors this is just data, make it

struct Car
{
Car( std::string const& aModel, int aYear, TCarType aCategory )
: model( aModel ), year( aYear ), category( aCategory )
{}

std::string model;
int year;
TCarType category;
};

Of course it is a good idea to encapsulate, to not have public data.

But your present design is public data (expressed in an impractical
way); if that's not your intention, get rid of all the setters.

By the way, I saw a delete[] further down in the code.

That's a bug, because what you're deleting is a literal string.
 
A

Alf P. Steinbach

* Alf P. Steinbach:
* (e-mail address removed):
Header File: car.h #if !defined CAR_H
#define CAR_H

enum TCarType { ctEconomy = 1, ctCompact, ctStandard, ctFullSize,
ctMiniVan, ctSUV };

class Car
{
public:
Car();
Car(char *MM, int Y, int Cat);
virtual ~Car();
void setMakeModel(const char *mm);
char* getMakeModel() const;
void setCarYear(const int y);
int getCarYear() const;
void setCategory(const int c);
int getCategory() const;

private:
char* MakeModel;
int CarYear;
int Category;
};

Except for the constructors this is just data, make it

struct Car
{
Car( std::string const& aModel, int aYear, TCarType aCategory )
: model( aModel ), year( aYear ), category( aCategory )
{}

std::string model;
int year;
TCarType category;
};

Of course it is a good idea to encapsulate, to not have public data.

But your present design is public data (expressed in an impractical
way); if that's not your intention, get rid of all the setters.

By the way, I saw a delete[] further down in the code.

That's a bug, because what you're deleting is a literal string.

Sorry, it's a bug, but I forgot what the bug was between the time of
reading the code and writing the reply. So the "because..." above is
wrong. Try to figure out what the bug is.
 
P

Phlip

How do I add exception-handling to this code and make sure it compiles
and runs properly?

That would be the subject of many books - most of them titled something like
/Exceptional C++/ by Herb Sutter.

Ordinarily, I would tell you to write unit tests for every step of your
code. However, a unit test cannot fail reliably if code is not
exception-safe, even if the test arranges for the code to throw exceptions,
then catches them. So the following is a spot-check.
Header File: car.h #if !defined CAR_H
#define CAR_H

enum TCarType { ctEconomy = 1, ctCompact, ctStandard, ctFullSize,
ctMiniVan, ctSUV };

class Car
{
public:
Car();
Car(char *MM, int Y, int Cat);
virtual ~Car();
void setMakeModel(const char *mm);
char* getMakeModel() const;

Why a char *? Why not a std::string?

And why does the get() return a non-constant pointer? In theory, its
implementation should not compile, but that's not going to help exception
safety.
Car::Car()

Right here, you ought to construct every variable. That means your pointers
should get NULL. (And they should then become std::string, which won't need
a constructor here.)

Proper construction is very important for exception safety because if
anything could throw then nothing should leak.
{
setMakeModel("No Car Selected");
setCarYear(2000);
setCategory(1);

That 1 should be ctEconomy.
//--------------------------------------------------------------------
Car::Car(char *MM, int Y, int Cat)
{
setMakeModel(MM);
setCarYear(Y);
setCategory(Cat);
}

You have two constructors doing nearly the same thing. That's okay in some
situations, but here you could just merge them like this:

Car::Car(char *MM = "No Car Selected", int Y = 2000, int Cat = ctEconomy)
void Car::setMakeModel(const char *m)
{
MakeModel = new char[strlen(m) + 1];
strcpy(MakeModel, m);
}

Right - MakeModel should be a std::string, so it would take care of the
buffer manipulations for you.

The remaining objections are nearly the same. Using more Standard Library
objects should reduce the odds of a leak if a stray exception throws.

In general you must make sure that all your objects destroy safely, and they
already do if they call 'delete'. The goal is to make your code safer for
programmers to edit and upgrade without risking its exception safety.
 
P

Peter

Header File: car.h #if !defined CAR_H
#define CAR_H

enum TCarType { ctEconomy = 1, ctCompact, ctStandard, ctFullSize,
ctMiniVan, ctSUV };

this enumeration should be part of the car class to avoid that it is
polluting the global name space.

class Car
{
public:
Car();

I doubt that you want an uninitialized car. There is no notion of
uninitialized cars in the real world thus there is also no need to have
such a car in your application.
If you need to use arrays of cars use arrays of pointers to cars.

Car(char *MM, int Y, int Cat);

I doubt that you want to pass a pointer to a writeable string here.
I guess it should be const char *MM.

virtual ~Car();
void setMakeModel(const char *mm);
char* getMakeModel() const;

I doubt that you want to return a pointer to a writeable string here.
I guess it should be


const char* getMakeModel() const;

or even better and more secure

std::string getMakeModel() const;

void setCarYear(const int y);
int getCarYear() const;
void setCategory(const int c);
int getCategory() const;

private:
char* MakeModel;

Why do you want to allocate string buffers by yourself?
Use std::string.
It is much less code and much more secure.

int CarYear;
int Category;
};

#endif // CAR_H



Source File: car.cpp // Car.cpp: implementation of the Car class.

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

#include "Car.h"

//--------------------------------------------------------------------
Car::Car()
{
setMakeModel("No Car Selected");
setCarYear(2000);
setCategory(1);
}
//--------------------------------------------------------------------
Car::Car(char *MM, int Y, int Cat)
{
setMakeModel(MM);
setCarYear(Y);
setCategory(Cat);
}
//--------------------------------------------------------------------
Car::~Car()
{
// delete [] MakeModel;
}
//--------------------------------------------------------------------
void Car::setMakeModel(const char *m)
{
MakeModel = new char[strlen(m) + 1];
strcpy(MakeModel, m);
}
//--------------------------------------------------------------------
char* Car::getMakeModel() const
{
return MakeModel;
}
//--------------------------------------------------------------------
void Car::setCarYear(const int y)
{
CarYear = y;
}
//--------------------------------------------------------------------
int Car::getCarYear() const
{
return CarYear;
}
//--------------------------------------------------------------------
void Car::setCategory(const int c)
{
Category = c;
}
//--------------------------------------------------------------------
int Car::getCategory() const
{
return Category;
}
//--------------------------------------------------------------------



Header File: customer.h #if !defined CUSTOMER_H
#define CUSTOMER_H

class Customer
{
private:
char* FirstName;
char* LastName;
char* Address;
char* City;
char* State;


use std::string instead of char * here.
e.g.
std::string FirstName;


long ZIPCode;

public:
void setFirstName(const char *FN);

a person usually does not have such a method -- thus you also don't
need it inside an application.
You can create persons with the correct name in a single step.
If the name is wrong, delete the person.

char* getFirstName() const { return FirstName; }


you want to return const char * here.

void setLastName(const char *LN);
char* getLastName() const { return LastName; }

same here
char* FullName() const;

same here
void setAddress(const char *Adr);
char* getAddress() const { return Address; }

same here
void setCity(const char *CT);
char* getCity() const { return City; }

same here
void setState(const char *St);
char* getState() const { return State; }

same here
void setZIPCode(const long ZIP);
long getZIPCode() const { return ZIPCode; }
Customer();

there is no need for an uninitialized customers.
You won't have such customers in the real world.

Customer(char *FName, char *LName, char *Adr,
char *Ct, char *St, long ZIP);


you may want to pass a const char * for all the strings,
since you constructor does not change these strings.

Customer(const Customer &Pers);
Customer(char * FName, char * LName);

same here
~Customer();
};

#endif // CUSTOMER_H



Source File: customer.cpp
//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
#pragma hdrstop

#include "Customer.h"

//---------------------------------------------------------------------------
char *Customer::FullName() const
{
char *FName = new char[40];
strcpy(FName, FirstName);
strcat(FName, " ");
strcat(FName, LastName);

return FName;
}


you definitely want this function to return a std::string.
Right now you have here a memory leak and also a potential buffer
overflow.
e.g.

member objects:

std::string FirstName, LastName;

function:
std::string Customer::FullName() const
{
std::string sName = FirstName + " " + LastName;

return sName;
}
//---------------------------------------------------------------------------
Customer::Customer()
: ZIPCode(0)
{
FirstName = new char[20];
strcpy(FirstName, "John");
LastName = new char[20];
strcpy(LastName, "Doe");
Address = new char[40];
strcpy(Address, "123 Main Street Apt A");
City = new char[32];
strcpy(City, "Great City");
State = new char[30];
strcpy(State, "Our State");


I would try to avoid having a default customer.
If you need array of customers make it an array of customer pointers.

}
//---------------------------------------------------------------------------
Customer::Customer(char * FName, char * LName)
: ZIPCode(0)
{
FirstName = new char[strlen(FName) + 1];
strcpy(FirstName, FName);
LastName = new char[strlen(LName) + 1];
strcpy(LastName, LName);
Address = new char[40];
strcpy(Address, "123 Main Street Apt A");
City = new char[32];
strcpy(City, "Great City");
State = new char[30];
strcpy(State, "Our State");
}
//---------------------------------------------------------------------------
Customer::Customer(char *FName, char *LName, char *Adr,
char *Ct, char *St, long ZIP)
: ZIPCode(ZIP)
{
FirstName = new char[strlen(FName) + 1];
strcpy(FirstName, FName);
LastName = new char[strlen(LName) + 1];
strcpy(LastName, LName);
Address = new char[40];
strcpy(Address, Adr);
City = new char[32];
strcpy(City, Ct);
State = new char[30];
strcpy(State, St);
}
//---------------------------------------------------------------------------
Customer::Customer(const Customer &Pers)
: ZIPCode(Pers.ZIPCode)
{
FirstName = new char[strlen(Pers.FirstName) + 1];
strcpy(FirstName, Pers.FirstName);
LastName = new char[strlen(Pers.LastName) + 1];
strcpy(LastName, Pers.LastName);
Address = new char[strlen(Pers.Address) + 1];
strcpy(Address, Pers.Address);
City = new char[strlen(Pers.City) + 1];
strcpy(City, Pers.City);
State = new char[strlen(Pers.State) + 1];
strcpy(State, Pers.State);
}
//---------------------------------------------------------------------------
void Customer::setFirstName(const char *FN)
{
strcpy(FirstName, FN);
}
//---------------------------------------------------------------------------
void Customer::setLastName(const char *LN)
{
strcpy(LastName, LN);
}
//---------------------------------------------------------------------------
void Customer::setAddress(const char *Adr)
{
strcpy(Address, Adr);
}
//---------------------------------------------------------------------------
void Customer::setCity(const char *CT)
{
strcpy(City, CT);
}
//---------------------------------------------------------------------------
void Customer::setState(const char *St)
{
strcpy(State, St);
}
//---------------------------------------------------------------------------
void Customer::setZIPCode(const long ZIP)
{
ZIPCode = ZIP;
}
//---------------------------------------------------------------------------
Customer::~Customer()
{
delete [] FirstName;
delete [] LastName;
delete [] Address;
delete [] City;
delete [] State;
}
//---------------------------------------------------------------------------



Header File: Invoice.h

#if !defined INVOICE_H
#define INVOICE_H

#include "Customer.h"
#include "Car.h"
#include "RentDate.h"

class Invoice
{
public:
Invoice();
virtual ~Invoice();
Customer CustomerRegistration();
void CustomerInformation(const Customer& Pers);
Car CarSelection();
void CarSelected(const Car& Vehicle);
double CalculatePrice(const Car& Vehicle, double& Rate, int &Days);
void setMileage(const long g);
long getMileage() const;
void setTankLevel(const char *v);
char* getTankLevel() const;
void setCarCondition(const char *c);
char* getCarCondition() const;

void ProcessOrder();

an invoice object does not process an order.

void CarExamination();

an invoice object does does not perform a car examination.

void ShowOrder();


an invoice object may be able to display itself -- pass the output
stream as an argument.


private:
long Mileage;
char *TankLevel;
char *CarCondition;

make these two a std::string.
From my understanding member objects belong at the beginning of the
class,
since their construction comes immediately after the base class
construction.
So you may want to see in a single view what happens during
construction.


};

#endif // INVOICE_H


Source File: Invoice.cpp

// Invoice.cpp: implementation of the Invoice class.
//
//////////////////////////////////////////////////////////////////////
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

#include "Invoice.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Invoice::Invoice()
{
setTankLevel("Empty");
setCarCondition("Good");
}
//--------------------------------------------------------------------
Invoice::~Invoice()
{
}
//--------------------------------------------------------------------
Customer Invoice::CustomerRegistration()
{
char FName[20], LName[20], Addr[40], CT[32], St[30];


Avoid fixed sized string buffers like the plague.
Use std::string.

long ZC = 0;

cout << "Enter Customer Information\n";
cout << "First Name: "; cin >> FName;
cout << "Last Name: "; cin >> LName;
cout << "Address: "; cin >> ws;
cin.getline(Addr, 40);
cout << "City: ";
cin.getline(CT, 32);
cout << "State: ";
cin.getline(St, 30);
cout << "Zip Code: "; cin >> ZC;

Customer Cust(FName, LName, Addr, CT, St, ZC);
return Cust;
}
//--------------------------------------------------------------------
Car Invoice::CarSelection()
{
int CarType, ModelChosen;
char strCarSelected[20];

same problem here.
int CarSelectedYear = 2000;

cout << "What type of car would you like to rent?";
do {
cout << "\n1 - Economy | 2 - Compact | 3 - Standard"
<< "\n4 - Full Size | 5 - Mini Van | 6 - Sports Utility";
cout << "\nYour Choice: ";
cin >> CarType;
if( CarType < 1 || CarType > 6 )
cout << "\nPlease type a number between 1 and 6";
} while(CarType < 1 || CarType > 6);

switch(CarType)
{
case ctEconomy:
cout << "\nFor the Economy type, we have:"
<< "\n1 - Daewoo Lanos | 2 - Cheverolet Metro";
cout << "\nWhich one would you prefer? ";
cin >> ModelChosen;

if(ModelChosen == 1)
{
strcpy(strCarSelected, "Daewoo Lanos");
CarSelectedYear = 1999;


I would rather go with enumerations for car types.

}
else
{
strcpy(strCarSelected, "Chevrolet Metro");
CarSelectedYear = 1998;
}
break;

case ctCompact:
cout << "\nFor the Compact type, we have:"
<< "\n1 - Chevrolet Cavalier | 2 - Dogde Neon"
<< "\n3 - Nissan Sentra | 4 - Toyota Corolla";
cout << "\nWhich one would you prefer? ";
cin >> ModelChosen;

if(ModelChosen == 1)
{
strcpy(strCarSelected, "Chevrolet Cavalier");
CarSelectedYear = 1999;
}
else if(ModelChosen == 2)
{
strcpy(strCarSelected, "Dodge Neon");
CarSelectedYear = 2001;
}
else if(ModelChosen == 3)
{
strcpy(strCarSelected, "Nissan Sentra");
CarSelectedYear = 1998;
}
else
{
strcpy(strCarSelected, "Toyota Corrolla");
CarSelectedYear = 2002;
}
break;

case ctStandard:
cout << "\nFor the Standard type, we have:"
<< "\n1 - Chevrolet Monte Carlo | 2 - Toyota Camri";
cout << "\nWhich one would you prefer? ";
cin >> ModelChosen;

if(ModelChosen == 1)
{
strcpy(strCarSelected, "Chevrolet Monte Carlo");
CarSelectedYear = 2000;
}
else
{
strcpy(strCarSelected, "Toyota Camri");
CarSelectedYear = 1998;
}
break;

case ctFullSize:
cout << "\nFor the Full Size type, we have:"
<< "\n1 - Chrysler 300M | 2 - Buick Century | 3 - Infinity I30";
cout << "\nWhich one would you prefer? ";
cin >> ModelChosen;

if(ModelChosen == 1)
{
strcpy(strCarSelected, "Chrysler 300M");
CarSelectedYear = 2000;
}
else if(ModelChosen == 2)
{
strcpy(strCarSelected, "Buick Century");
CarSelectedYear = 1999;
}
else
{
strcpy(strCarSelected, "Infinity I30");
CarSelectedYear = 2003;
}
break;

case ctMiniVan:
cout << "\nFor the Mini-Van type, we have:"
<< "\n1 - Dodge Caravan | 2 - Dodge Caravan"
<< "\n3 - Pontiac Montana | 4 - Pontiac Montana | 5 - Chevrolet
Astro Van";
cout << "\nWhich one would you prefer? ";
cin >> ModelChosen;

if(ModelChosen == 1)
{
strcpy(strCarSelected, "Dodge Caravan");
CarSelectedYear = 2001;
}
else if(ModelChosen == 2)
{
strcpy(strCarSelected, "Dodge Caravan");
CarSelectedYear = 2003;
}
else if(ModelChosen == 3)
{
strcpy(strCarSelected, "Pontiac Montana");
CarSelectedYear = 2003;
}
else
{
strcpy(strCarSelected, "Chevrolet Astro Van");
CarSelectedYear = 2000;
}
break;

case ctSUV:
cout << "\nFor the Sport Utility type, we have:"
<< "\n1 - GMC Jimmy | 2 - Jeep Cherokee"
<< "\n3 - Chevrolet Blazer | 4 - Toyota Pathfinder";
cout << "\nWhich one would you prefer? ";
cin >> ModelChosen;

if(ModelChosen == 1)
{
strcpy(strCarSelected, "GMC Jimmy");
CarSelectedYear = 1998;
}
else if(ModelChosen == 2)
{
strcpy(strCarSelected, "Jeep Cherokee");
CarSelectedYear = 2003;
}
else if(ModelChosen == 3)
{
strcpy(strCarSelected, "Chevrolet Blazer");
CarSelectedYear = 2001;
}
else
{
strcpy(strCarSelected, "Toyota Pathfinder");
CarSelectedYear = 2000;
}
break;
}

Car Selected(strCarSelected, CarSelectedYear, CarType);
return Selected;
}
//--------------------------------------------------------------------
void Invoice::setMileage(const long g)
{
Mileage = g;
}
//--------------------------------------------------------------------
long Invoice::getMileage() const
{
return Mileage;
}
//--------------------------------------------------------------------
void Invoice::setTankLevel(const char *v)
{
TankLevel = new char[strlen(v) + 1];
strcpy(TankLevel, v);
}
//--------------------------------------------------------------------
char* Invoice::getTankLevel() const
{
return TankLevel;
}
//--------------------------------------------------------------------
void Invoice::setCarCondition(const char *c)
{
CarCondition = new char[strlen(c) + 1];
strcpy(CarCondition, c);
}
//--------------------------------------------------------------------
char* Invoice::getCarCondition() const
{
return CarCondition;
}
//--------------------------------------------------------------------
void Invoice::processOrder()
{
int NbrOfDays;;
double Rate, TotalPrice;
// Enter Customer Information
Customer Person = CustomerRegistration();
cout << "\nProcess Car Information\n";
Car Driving = CarSelection();

TotalPrice = CalculatePrice(Driving, Rate, NbrOfDays);
CarExamination();

// This function works for both Borland C++ Builder and MSVC
system("cls");

cout << " - Bethesda Car Rental -";
cout << "\n=============================";
CustomerInformation(Person);
cout << "\n------------------------------";
CarSelected(Driving);
cout << setiosflags(ios::fixed) << setprecision(2);
cout << "\n------------------------------";
cout << "\nCar Mileage: " << getMileage();
cout << "\nCondition: " << getCarCondition();
cout << "\nTank Level: " << getTankLevel();
cout << "\n# of Days: " << NbrOfDays;
cout << "\n------------------------------";
cout << "\nRate: $" << Rate;
cout << "\nTotal Price: $" << TotalPrice;
cout << "\n==============================\n";
}
//--------------------------------------------------------------------
void Invoice::CustomerInformation(const Customer& Pers)
{
cout << "\nEmployee Identification";
cout << "\nFull Name: " << Pers.FullName();
cout << "\nAddress: " << Pers.getAddress();
cout << "\nCity: " << Pers.getCity() << ", "
<< Pers.getState() << " " << Pers.getZIPCode();
}
//--------------------------------------------------------------------
void Invoice::CarSelected(const Car& Vehicle)
{
cout << "\nModel: " << Vehicle.getMakeModel();
cout << "\nYear: " << Vehicle.getCarYear();
}

//--------------------------------------------------------------------
double Invoice::CalculatePrice(const Car& Vehicle, double& DayRate,
int &NumberOfDays)
{
// char WeekEndResponse;// Does the customer rent the car for the
week-end?
double OneDayRate, // If renting for less than 5 days including
week-end
WeekDay, // If renting for at least 5 days, regardless of the days
WeekEnd = 0;// If renting for more than two days from Friday to
monday
//double DayRate; // Rate applied based on the number of days
double TotalRate;

switch(Vehicle.getCategory())
{
case ctEconomy:
DayRate = 24.95;
OneDayRate = 29.95;
WeekDay = 24.95;
WeekEnd = 19.95;
break;

case ctCompact:
DayRate = 34.95;
OneDayRate = 39.95;
WeekDay = 34.95;
WeekEnd = 25.95;
break;

case ctStandard:
DayRate = 38.95;
OneDayRate = 49.95;
WeekDay = 38.95;
WeekEnd = 32.95;
break;

case ctFullSize:
DayRate = 44.95;
OneDayRate = 69.95;
WeekDay = 44.95;
WeekEnd = 35.95;
break;

case ctMiniVan:
DayRate = 54.95;
OneDayRate = 89.95;
WeekDay = 54.95;
WeekEnd = 42.95;
break;

case ctSUV:
DayRate = 64.95;
OneDayRate = 89.95;
WeekDay = 64.95;
WeekEnd = 50.95;
break;
}

cout << "\nHow many days? "; cin >> NumberOfDays;
TotalRate = DayRate * NumberOfDays;
return TotalRate;
}
//--------------------------------------------------------------------
void Invoice::CarExamination()
{
char Cond;
int GasLevel;

cout << "Rate the car's condition (e=Excellent/g=Good/d=Driveable): ";
cin >> Cond;
if( Cond == 'e' || Cond == 'E' )
strcpy(CarCondition, "Excellent");
else if( Cond == 'g' || Cond == 'G' )
strcpy(CarCondition, "Good");
else if( Cond == 'd' || Cond == 'D' )
strcpy(CarCondition, "Driveable");
else
strcpy(CarCondition, "Can't Decide");

cout << "Enter the car mileage: ";
cin >> Mileage;

do {
cout << "Gas level in the tank"
<< "\n1 - Considered Empty"
<< "\n2 - 1/4 Full"
<< "\n3 - Half Full"
<< "\n4 - 3/4 Full"
<< "\n5 - Full Tank";
cout << "\nEnter the gas level: ";
cin >> GasLevel;
}while(GasLevel < 1 || GasLevel > 5);

switch(GasLevel)
{
case 1:
setTankLevel("Empty");
break;
case 2:
setTankLevel("1/4 Full");
break;
case 3:
setTankLevel("Half Full");
break;
case 4:
setTankLevel("3/4 Full");
break;
case 5:
setTankLevel("Full Tank");
break;
}
}
//--------------------------------------------------------------------


Main File: Main.cpp

#include "Invoice.h"

void main()
{
CInvoice Order;

Order.ProcessOrder();
Order.ShowOrder();
}


I don't see any errors which you may want to convert into C++
Exceptions.
C++ Exceptions are superiour to return codes, as they may contain a lot
more information
and you don't need to check for return codes.
Remember also that using C++ Exceptions you can abort the construction
of an object.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top