A common technique used to create programs with various objects
consists of declaring one object inside of another. Once you have or know the object
to use, you can declare it like a regular member of the object. Like another member
variable, you can initialize the object and even manipulate its members.
Using an Enumerator as an Object Member |
|
The enumerators we have used so far were intended to simply carry
a list of constant integers. This is useful for conditional statements where a switch
or an if…else statements would need to perform comparisons. As an example, suppose we
create the following class:
//---------------------------------------------------------------------------
#ifndef LabelTypeH
#define LabelTypeH
//---------------------------------------------------------------------------
#include <string>
using namespace std;
//---------------------------------------------------------------------------
enum TPrintCategory { pcInkjet = 1, pcLaser, pcMultiPurpose, pcUnspecified };
//---------------------------------------------------------------------------
class TLabelType
{
public:
TLabelType();
TLabelType(unsigned int m, string n, string c, int t);
TLabelType(const TLabelType& Label);
~TLabelType();
void setModelNumber(const unsigned int m) { ModelNumber = m; }
void setName(const string n) { Name = n; }
void setColor(const string c) { Color = c; }
void setPrintType(const int i) { PrintType = i; }
unsigned int getModelNumber() const;
string getName() const;
string getColor() const;
string getPrintType() const;
private:
unsigned int ModelNumber;
string Name;
string Color;
int PrintType;
};
//---------------------------------------------------------------------------
#endif
To demonstrate the use of this new enumerator, we could implement the getPrintType() function as follows:
//---------------------------------------------------------------------------
#include "LabelType.h"
//---------------------------------------------------------------------------
TLabelType::TLabelType()
: ModelNumber(0),
Name("None"),
Color("White"),
PrintType(3)
{
}
//---------------------------------------------------------------------------
TLabelType::TLabelType(unsigned int m, string n, string c, int t)
: ModelNumber(m),
Name(n),
Color(c),
PrintType(t)
{
}
//---------------------------------------------------------------------------
TLabelType::TLabelType(const TLabelType& Label)
: ModelNumber(Label.ModelNumber),
Name(Label.Name),
Color(Label.Color),
PrintType(Label.PrintType)
{
}
//---------------------------------------------------------------------------
TLabelType::~TLabelType()
{
}
//---------------------------------------------------------------------------
unsigned int TLabelType::getModelNumber() const
{
return ModelNumber;
}
//---------------------------------------------------------------------------
string TLabelType::getName() const
{
return Name;
}
//---------------------------------------------------------------------------
string TLabelType::getColor() const
{
return Color;
}
//---------------------------------------------------------------------------
string TLabelType::getPrintType() const
{
string PrintingType;
switch( PrintType )
{
case pcInkjet:
PrintingType = "Injet";
break;
case pcLaser:
PrintingType = "Laser";
break;
case pcMultiPurpose:
PrintingType = "Multi-Purpose";
break;
default:
PrintingType = "Unspeficied";
}
return PrintingType;
}
//---------------------------------------------------------------------------
We can test our object using the main() function as follows:
//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
#include "LabelType.h"
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TLabelType Label;
cout << "A label with default characteristics";
cout << "\nModel Number: " << Label.getModelNumber();
cout << "\nModel Name: " << Label.getName();
cout << "\nMain Color: " << Label.getColor();
cout << "\nPrinting Type: " << Label.getPrintType();
cout << "\n\n";
Label.setModelNumber(475832);
Label.setName("Blanc d'Azure");
Label.setColor("Old Sand");
Label.setPrintType(2);
cout << "Custom Label";
cout << "\nModel Number: " << Label.getModelNumber();
cout << "\nModel Name: " << Label.getName();
cout << "\nMain Color: " << Label.getColor();
cout << "\nPrinting Type: " << Label.getPrintType();
return 0;
}
//---------------------------------------------------------------------------
Besides representing a list of constant integers, an enumerator can also behave like a small object, making it one of the most commonly used members of objects in C++ Builder applications. As a semi-complete data type, an enumerator can be used to create an integer data type and make it a member of another object. The advantage of using an enumerator is that, unlike a regular integer, an enumerator and its members names are a little more explicit. You will see this technique used on many objects of the Visual Component Library.
We have learned that, when defining an enumerator, we can supply the names of its members. Here is an example:
enum TAdhesive { adNone, adRemovable, adNonRemovable };
Once the enumerator is defined, we can declare it as a member of an object where needed. The enumerator becomes a data type. It can be declared as a variable:
It can also be passed as an argument:
TLabelType(long m, string c, string n, TAdhesive a);
|
Or it can de used as a return type of a function or a method:
TAdhesive getAdhesive();
These characteristics of an enumerator are exemplified in the new version of the TLabelType object as follows:
//---------------------------------------------------------------------------
#ifndef LabelTypeH
#define LabelTypeH
//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
enum TPrintCategory { pcInkjet = 1, pcLaser, pcMultiPurpose, pcUnspecified };
enum TAdhesive { adNone, adRemovable, adNonRemovable };
//---------------------------------------------------------------------------
class TLabelType
{
public:
TLabelType();
TLabelType(unsigned int m, string n, string c,
int t, TAdhesive a);
TLabelType(const TLabelType& Label);
~TLabelType();
void setModelNumber(const unsigned int m) { ModelNumber = m; }
void setName(const string n) { Name = n; }
void setColor(const string c) { Color = c; }
void setPrintType(const int i) { PrintType = i; }
void setAdhesive(TAdhesive a) { Adhesive = a; }
unsigned int getModelNumber() const;
string getName() const;
string getColor() const;
string getPrintType() const;
TAdhesive getAdhesive() const;
private:
unsigned int ModelNumber;
string Name;
string Color;
int PrintType;
TAdhesive Adhesive;
};
//---------------------------------------------------------------------------
#endif
When implementing the object, if you want to initialize a variable identified by an enumerator, make sure you use a valid name as one of the members of the enumerator. An example would be:
Adhesive = adNonRemovable;
You could be tempted to use a constant integer to initialize such a variable. Here is an example:
Adhesive = 1;
But this is a bad idea. First the use of the enumerator would appear pointless and unprofessional because this would deceive the purpose of using an enumerator. Second, if you initialize the variable using a valid name, the compiler would have the responsibility of finding the corresponding value of the member; if you decide to use a (random) integer, no matter how confident you are, you are running the risk of using a value unrecognized by the enumerator. Thirdly, most compilers would display a warning; and you
should not neglect warnings.
To implement the functions whose return type or arguments are enumerator, proceed as you would for other regular data types. Here is the source file of the TLabelType object:
#include "LabelType.h"
//---------------------------------------------------------------------------
TLabelType::TLabelType()
: ModelNumber(0),
Name("None"),
Color("White"),
PrintType(3),
Adhesive(adNone)
{
}
//---------------------------------------------------------------------------
TLabelType::TLabelType(unsigned int m, string n, string c,
int t, TAdhesive a)
: ModelNumber(m),
Name(n),
Color(c),
PrintType(t),
Adhesive(a)
{
}
//---------------------------------------------------------------------------
TLabelType::TLabelType(const TLabelType& Label)
: ModelNumber(Label.ModelNumber),
Name(Label.Name),
Color(Label.Color),
PrintType(Label.PrintType),
Adhesive(Label.Adhesive)
{
}
//---------------------------------------------------------------------------
. . .
//---------------------------------------------------------------------------
TAdhesive TLabelType::getAdhesive() const
{
return Adhesive;
}
//---------------------------------------------------------------------------
|
Using the main() function, a test of the program would be as follows:
//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
#include "LabelType.h"
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TLabelType Label;
cout << "A label with default characteristics";
cout << "\nModel Number: " << Label.getModelNumber();
cout << "\nModel Name: " << Label.getName();
cout << "\nMain Color: " << Label.getColor();
cout << "\nPrinting Type: " << Label.getPrintType();
cout << "\nAdhesive Type: " << Label.getAdhesive();
cout << "\n\n";
Label.setModelNumber(475832);
Label.setName("Blanc d'Azure");
Label.setColor("Old Sand");
Label.setPrintType(2);
Label.setAdhesive(adRemovable);
cout << "Custom Label";
cout << "\nModel Number: " << Label.getModelNumber();
cout << "\nModel Name: " << Label.getName();
cout << "\nMain Color: " << Label.getColor();
cout << "\nPrinting Type: " << Label.getPrintType();
cout << "\nAdhesive Type: " << Label.getAdhesive();
return 0;
}
//---------------------------------------------------------------------------
|
|
Using Enumerators and Classes |
- Start your programming environment. Create a new C++ based Console Application
- Save the project in a new folder called Student2. Save the first file as Main and the project as ROSH
- Create a new class and save it as Students
- Create the header file as follows:
//---------------------------------------------------------------------------
#ifndef StudentsH
#define StudentsH
#include <iostream>
//---------------------------------------------------------------------------
enum TStudentGender { sgUnspecified, sgMale, sgFemale };
//---------------------------------------------------------------------------
class TStudents
{
public:
TStudents();
TStudents(string fn, string ln,
int DOB, int MOB, int YOB, int g);
TStudents(string fn, string ln);
TStudents(int DOB, int MOB, int YOB);
TStudents(const TStudents& S);
~TStudents();
void setFirstName(const string f) { FirstName = f; }
string getFirstName() const { return FirstName; }
void setLastName(const string l) { LastName = l; }
string getLastName() const { return LastName; }
void setDayOfBirth(const int d) { DayOfBirth = d; }
int getDayOfBirth() const { return DayOfBirth; }
void setMonthOfBirth(const int m) { MonthOfBirth = m; }
int getMonthOfBirth() const { return MonthOfBirth; }
void setYearOfBirth(const int y) { YearOfBirth = y; }
int getYearOfBirth() const { return YearOfBirth; }
void setGender(const int g) { Gender = g; }
string getGender() const;
private:
string FirstName;
string LastName;
int DayOfBirth;
int MonthOfBirth;
int YearOfBirth;
int Gender;
};
//---------------------------------------------------------------------------
#endif
|
- Implement the source file as follows:
//---------------------------------------------------------------------------
using namespace std;
#include "Students.h"
//---------------------------------------------------------------------------
TStudents::TStudents()
: FirstName("John"),
LastName("Doe"),
DayOfBirth(5),
MonthOfBirth(10),
YearOfBirth(1988),
Gender(0)
{
}
//---------------------------------------------------------------------------
TStudents::TStudents(string fn, string ln,
int DOB, int MOB, int YOB, int g)
: FirstName(fn), LastName(ln),
DayOfBirth(DOB), MonthOfBirth(MOB), YearOfBirth(YOB), Gender(g)
{
}
//---------------------------------------------------------------------------
TStudents::TStudents(string fn, string ln)
: FirstName(fn), LastName(ln),
DayOfBirth(1), MonthOfBirth(1), YearOfBirth(1990)
{
}
//---------------------------------------------------------------------------
TStudents::TStudents(int DOB, int MOB, int YOB)
{
FirstName = "Peter";
LastName = "Mukoko";
DayOfBirth = DOB;
MonthOfBirth = MOB;
YearOfBirth = YOB;
}
//---------------------------------------------------------------------------
TStudents::TStudents(const TStudents& Stud)
: FirstName(Stud.FirstName), LastName(Stud.LastName),
DayOfBirth(Stud.DayOfBirth), MonthOfBirth(Stud.MonthOfBirth),
YearOfBirth(Stud.YearOfBirth), Gender(Stud.Gender)
{
}
//---------------------------------------------------------------------------
TStudents::~TStudents()
{
}
//---------------------------------------------------------------------------
string TStudents::getGender() const
{
if( Gender == sgMale )
return "Male";
else if( Gender == sgFemale )
return "Female";
else
return "Unspecified";
}
//---------------------------------------------------------------------------
|
- To prepare a test of the program, change the content of the Main.cpp file as follows:
//---------------------------------------------------------------------------
#include <iomanip>
#include <conio.h>
using namespace std;
//---------------------------------------------------------------------------
#include "Students.h"
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TStudents S;
string FN, LN;
int Day, Month, Year, Gdr;
cout << "Enter the student's information\n";
cout << "First Name: "; cin >> FN;
cout << "Last Name: "; cin >> LN;
cout << "Day of Birth: "; cin >> Day;
cout << "Month of Birth: "; cin >> Month;
cout << "Year of Birth: "; cin >> Year;
cout << "Gender: ";
cout << "\n1 - Male"
<< "\n2 - Female"
<< "\n3 - Unspecified"
<< "\nYour Choice: ";
cin >> Gdr;
S.setFirstName(FN);
S.setLastName(LN);
S.setDayOfBirth(Day);
S.setMonthOfBirth(Month);
S.setYearOfBirth(Year);
S.setGender(Gdr);
system("cls");
cout << "=======================================";
cout << "\nStudent Registration";
cout << "\nFull Name: "
<< S.getFirstName() << " "
<< S.getLastName();
cout << "\nDate of Birth: "
<< S.getDayOfBirth() << "/"
<< S.getMonthOfBirth() << "/"
<< S.getYearOfBirth();
cout << "\nGender: " << S.getGender();
return 0;
}
//---------------------------------------------------------------------------
|
- To test the program, on the main menu, click Run -> Run.
- After testing the program, return to your programming environment.
Direct Access of a Member of Another Object |
|
The most basic technique of making one object a member of another is to simply declare it as if it were a (regular) member variable, using the same technique you would for another variable. Suppose you add the following class to the label project:
//---------------------------------------------------------------------------
#ifndef LabelDimensionsH
#define LabelDimensionsH
using namespace std;
//---------------------------------------------------------------------------
class TDimensions
{
public:
TDimensions(Double L = 0.00, Double W = 0.00);
~TDimensions();
void setDimensions(const Double L, const Double H);
Double getLength() const { return Length; }
Double getHeight() const { return Height; }
Double Area() const;
private:
Double Length;
Double Height;
};
//---------------------------------------------------------------------------
#endif
|
And suppose you implement the class as follows:
//---------------------------------------------------------------------------
using namespace std;
#include "LabelDimensions.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
TDimensions::TDimensions(Double L, Double W)
: Length(L), Height(H)
{
//TODO: Add your source code here
}
//---------------------------------------------------------------------------
TDimensions::~TDimensions()
{
//TODO: Add your source code here
}
//---------------------------------------------------------------------------
void TDimensions::setDimensions(const Double L, const Double H)
{
Length = L;
Height = H;
}
//---------------------------------------------------------------------------
Double TDimensions::Area() const
{
return Length * Height;
}
//---------------------------------------------------------------------------
|
Here is an example of making it a member of the TLabelType class:
//---------------------------------------------------------------------------
#ifndef LabelTypeH
#define LabelTypeH
//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
#include "LabelDimensions.h"
//---------------------------------------------------------------------------
enum TPrintCategory { pcInkjet = 1, pcLaser, pcMultiPurpose, pcUnspecified };
enum TAdhesive { adNone, adRemovable, adNonRemovable };
//---------------------------------------------------------------------------
class TLabelType
{
public:
. . .
TDimensions Dim;
private:
. . .
};
//---------------------------------------------------------------------------
#endif
|
|
When an object B is made a member of another object A, you can access the member variables of the member object B using the member access operator (.). As a result, you would be using two period operators. After declaring the main object, the first operator is used to access the members of the main object, usually the constructor. The second operator, if used, allows accessing a member of the dependent object. Here is an example:
//---------------------------------------------------------------------------
#include <iomanip>
using namespace std;
//---------------------------------------------------------------------------
#include "LabelType.h"
#include "LabelDimensions.h"
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TLabelType LblType;
string AdhesiveType;
cout << "A label with default characteristics";
cout << setiosflags(ios::fixed) << setprecision(2);
cout << "\n Dimensions: "
<< LblType.Dim.getLength() << " * " << LblType.Dim.getHeight();
cout << "\n Area: " << LblType.Dim.Area();
cout << "\n Model Number: " << LblType.getModelNumber();
cout << "\n Model Name: " << LblType.getName();
cout << "\n Main Color: " << LblType.getColor();
cout << "\n Printing Type: " << LblType.getPrintType();
cout << "\n Adhesive Type: " << LblType.getAdhesive();
cout << "\n\n";
LblType.Dim.setDimensions(4.25, 2.50);
LblType.setModelNumber(38946);
LblType.setName("Coast Layer");
LblType.setColor("Bone White");
LblType.setPrintType(2);
LblType.setAdhesive(adRemovable);
if( LblType.getAdhesive() == adRemovable )
AdhesiveType = "Removable";
else if( LblType.getAdhesive() == adNonRemovable )
AdhesiveType = "Non-Removable";
else
AdhesiveType = "None";
cout << "Customer Defined Label";
cout << "\n Dimensions: "
<< LblType.Dim.getLength() << " * " << LblType.Dim.getHeight();
cout << "\n Area: " << LblType.Dim.Area();
cout << "\n Model Number: " << LblType.getModelNumber();
cout << "\n Model Name: " << LblType.getName();
cout << "\n Main Color: " << LblType.getColor();
cout << "\n Printing Type: " << LblType.getPrintType();
cout << "\n Adhesive Type: " << AdhesiveType;
return 0;
}
//---------------------------------------------------------------------------
|
The period operator can also be used when allowing the user to provide the properties of the object. Using this ability, you can design a program to request the needed values.
|
An Object as a Member Variable |
- Add a new class and save it as Grades
- To declare one object as a member of another object, add a new class saved as Grades and create its TGrades class as follows:
//---------------------------------------------------------------------------
#ifndef GradesH
#define GradesH
#include "Students.h"
//---------------------------------------------------------------------------
class TGrades
{
public:
TGrades();
TGrades(double e, double s, double h,
double g, double c, double o,
double m, double p, double r, double t);
~TGrades();
void setEnglish(const double e) { English = e; }
double getEnglish() const { return English; }
void setSecondLng(const double s) { SecondLng = s; }
double getSecondLng() const { return SecondLng; }
void setHistory(const double h) { History = h; }
double getHistory() const { return History; }
void setGeography(const double g) { Geography = g; }
double getGeography() const { return Geography; }
void setChemistry(const double c) { Chemistry = c; }
double getChemistry() const { return Chemistry; }
void setSociology(const double o) { Sociology = o; }
double getSociology() const { return Sociology; }
void setMath(const double m) { Math = m; }
double getMath() const { return Math; }
void setCompSc(const double p) { CompSc = p; }
double getCompSc() const { return CompSc; }
void setMorale(const double a) { Morale = a; }
double getMorale() const { return Morale; }
void setSports(const double t) { Sports = t; }
double getSports() const { return Sports; }
double CalcTotal() const;
double CalcMean() const;
TStudents Identification;
private:
double English;
double SecondLng;
double History;
double Geography;
double Chemistry;
double Sociology;
double Math;
double CompSc;
double Morale;
double Sports;
};
//---------------------------------------------------------------------------
#endif
|
- Implement the TGrades class as follows:
//---------------------------------------------------------------------------
using namespace std;
#include "Grades.h"
//---------------------------------------------------------------------------
TGrades::TGrades()
{
English = 0.00;
SecondLng = 0.00;
History = 0.00;
Geography = 0.00;
Chemistry = 0.00;
Sociology = 0.00;
Math = 0.00;
CompSc = 0.00;
Morale = 0.00;
Sports = 0.00;
}
//---------------------------------------------------------------------------
TGrades::TGrades(double e, double s, double h,
double g, double c, double o,
double m, double p, double r, double t)
{
English = e;
SecondLng = s;
History = h;
Geography = g;
Chemistry = c;
Sociology = o;
Math = m;
CompSc = p;
Morale = r;
Sports = t;
}
//---------------------------------------------------------------------------
TGrades::~TGrades()
{
//TODO: Add your source code here
}
//---------------------------------------------------------------------------
double TGrades::CalcTotal() const
{
double Total = English + SecondLng + History +
Geography + Chemistry + Sociology +
Math + CompSc + Morale + Sports;
return Total;
}
//---------------------------------------------------------------------------
double TGrades::CalcMean() const
{
return CalcTotal() / 10;
}
//---------------------------------------------------------------------------
|
- To prepare a test of the program, change the Main.cpp file as follows:
//---------------------------------------------------------------------------
#include <iomanip>
#include <conio.h>
using namespace std;
//---------------------------------------------------------------------------
#include "Grades.h"
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TGrades G;
string FN, LN;
int Day, Month, Year, Gdr;
cout << "Enter the student's information\n";
cout << "First Name: "; cin >> FN;
cout << "Last Name: "; cin >> LN;
cout << "Day of Birth: "; cin >> Day;
cout << "Month of Birth: "; cin >> Month;
cout << "Year of Birth: "; cin >> Year;
cout << "Gender: ";
cout << "\n1 - Male"
<< "\n2 - Female"
<< "\n3 - Unspecified"
<< "\nYour Choice: ";
cin >> Gdr;
G.Identification.setFirstName(FN);
G.Identification.setFirstName(FN);
G.Identification.setLastName(LN);
G.Identification.setDayOfBirth(Day);
G.Identification.setMonthOfBirth(Month);
G.Identification.setYearOfBirth(Year);
G.Identification.setGender(Gdr);
double Language1, Language2, Hist, Geog, Chem, Soc,
Math, CompSc, Mor, Sport;
cout << "English: "; cin >> Language1;
cout << "2nd Language: "; cin >> Language2;
cout << "History: "; cin >> Hist;
cout << "Geography: "; cin >> Geog;
cout << "Chemistry: "; cin >> Chem;
cout << "Sociology: "; cin >> Soc;
cout << "Mathematics: "; cin >> Math;
cout << "Comp Sciences: "; cin >> CompSc;
cout << "Morale: "; cin >> Mor;
cout << "Sports: "; cin >> Sport;
G.setEnglish(Language1);
G.setSecondLng(Language2);
G.setHistory(Hist);
G.setGeography(Geog);
G.setChemistry(Chem);
G.setSociology(Soc);
G.setMath(Math);
G.setCompSc(CompSc);
G.setMorale(Mor);
G.setSports(Sport);
system("cls");
cout << "=======================================";
cout << "\nStudent Registration";
cout << "\nFull Name: "
<< G.Identification.getFirstName() << " "
<< G.Identification.getLastName();
cout << "\nDate of Birth: "
<< G.Identification.getDayOfBirth() << "/"
<< G.Identification.getMonthOfBirth() << "/"
<< G.Identification.getYearOfBirth();
cout << "\nGender: " << G.Identification.getGender();
cout << "\n------------------------------------------";
cout << setiosflags(ios::fixed) << setprecision(2);
cout << "\n\tEnglish: " << G.getEnglish();
cout << "\n\tLanguage 2: " << G.getSecondLng();
cout << "\n\tHistory: " << G.getHistory();
cout << "\n\tGeography: " << G.getGeography();
cout << "\n\tChemistry: " << G.getChemistry();
cout << "\n\tSociology: " << G.getSociology();
cout << "\n\tMathematics: " << G.getMath();
cout << "\n\tComp Sciences: " << G.getCompSc();
cout << "\n\tMorale: " << G.getMorale();
cout << "\n\tSports: " << G.getSports();
cout << "\n------------------------------------------";
cout << "\n\tTotal: " << G.CalcTotal()
<< "\tMean: " << G.CalcMean();
cout << "\n=======================================";
return 0;
}
//---------------------------------------------------------------------------
|
- To test the program, on the Debug toolbar, click the Run button . An example would be:
- Return to your programming environment.
Like a function, a class can be made a friend of another class. When class A is made a friend of class B, all members of class B are directly accessible to the members of class A; this includes private (and protected) members:
Friendship is not mutual: the fact that class A is made a friend of class B does not imply that class B is made a friend of class A. In other words, the fact that the (private and protected) members of class B are accessible to the members of class A does not mean that the members of class A area accessible to the members of class B.To process an order for labels, suppose you create the following class:
//---------------------------------------------------------------------------
#ifndef LabelsH
#define LabelsH
using namespace std;
//---------------------------------------------------------------------------
class TLabels
{
public:
TLabels();
TLabels(const TLabels& L);
~TLabels();
void ProcessALabel();
void setPrice(const Double p) { Price = p; }
Double getPrice() const { return Price; }
void ShowReceipt();
private:
Double Price;
};
//---------------------------------------------------------------------------
#endif
|
And suppose you implement it as follows:
//---------------------------------------------------------------------------
using namespace std;
#include "Labels.h"
//---------------------------------------------------------------------------
TLabels::TLabels()
: Price(0.00)
{
}
//---------------------------------------------------------------------------
TLabels::TLabels(const TLabels& L)
: Price(L.Price)
{
}
//---------------------------------------------------------------------------
TLabels::~TLabels()
{
}
//---------------------------------------------------------------------------
void TLabels::ProcessALabel()
{
// Get the dimensions of the label
// Get the label's characteristics
}
//---------------------------------------------------------------------------
void TLabels::ShowReceipt()
{
cout << "Label Order - Receipt";
cout << "\n\tDimensions: ";
cout << "\n\tArea: ";
cout << "\n\tModel No.: ";
cout << "\n\tModel Name: ";
cout << "\n\tColor: ";
cout << "\n\tAdhesive: ";
cout << "\n\tPrice: "
<< setiosflags(ios::fixed) << setprecision(2)
<< Price;
}
//---------------------------------------------------------------------------
|
To effectively process an order, the new class needs access to the dimensions and the characteristics of the label, which reside in two different classes. Therefore, we will give it unlimited access to the appropriate classes.
To make one class a friend of another, in the body of the class that is granting the friendship, type
friend class ClassName;
The keywords friend and class are required. The ClassName is the name of the class that needs friendship. Here is an example:
//---------------------------------------------------------------------------
#ifndef LabelDimensionsH
#define LabelDimensionsH
using namespace std;
//---------------------------------------------------------------------------
class TDimensions
{
friend class TLabels;
public:
TDimensions(Double L = 0.00, Double W = 0.00);
~TDimensions();
void setDimensions(const Double L, const Double H);
Double getLength() const { return Length; }
Double getHeight() const { return Height; }
Double Area() const;
private:
Double Length;
Double Height;
};
//---------------------------------------------------------------------------
#endif
|
A class can be made a friend of as many classes as necessary, as illustrated in the following other example:
//---------------------------------------------------------------------------
#ifndef LabelTypeH
#define LabelTypeH
//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
#include "LabelDimensions.h"
//---------------------------------------------------------------------------
enum TPrintCategory { pcInkjet = 1, pcLaser, pcMultiPurpose, pcUnspecified };
enum TAdhesive { adNone, adRemovable, adNonRemovable };
//---------------------------------------------------------------------------
class TLabelType
{
friend class TLabels;
public:
. . .
string getPrintType() const;
TAdhesive getAdhesive() const;
private:
unsigned int ModelNumber;
string Name;
string Color;
int PrintType;
TAdhesive Adhesive;
};
//---------------------------------------------------------------------------
#endif
|
Notice that, since a class used to process an order will also specify the dimensions, we do not need a TLabelDimensions member variable anymore. Now that the TLabels class has direct access to the other classes, we restructure it as
follows:
//---------------------------------------------------------------------------
#ifndef LabelsH
#define LabelsH
#include "LabelType.h"
#include "LabelDimensions.h"
//---------------------------------------------------------------------------
class TLabels
{
public:
TLabels();
TLabels(const TLabels& L);
~TLabels();
void GetLabelDimensions(TDimensions& Dim);
void GetLabelCharacteristics(TLabelType& Label);
void setPrice(const Double p) { Price = p; }
Double getPrice() const { return Price; }
void ShowReceipt(const TDimensions& Dim,
const TLabelType& Label);
private:
Double Price;
};
//---------------------------------------------------------------------------
#endif
|
To implement these functions, keep in mind that we have access to the private members of the other classes. This means that we can initialize their member or request their values without declaring variables to hold these values. Here is their implementations:
//---------------------------------------------------------------------------
#include <iomanip>
using namespace std;
#include "Labels.h"
//---------------------------------------------------------------------------
TLabels::TLabels()
: Price(0.00)
{
}
//---------------------------------------------------------------------------
TLabels::TLabels(const TLabels& L)
: Price(L.Price)
{
}
//---------------------------------------------------------------------------
TLabels::~TLabels()
{
}
//---------------------------------------------------------------------------
void TLabels::GetLabelDimensions(TDimensions& Rect)
{
cout << "Enter dimensions of the label\n";
cout << "Length: ";
cin >> Rect.Length;
cout << "Height: ";
cin >> Rect.Height;
Double A = Rect.Area();
if( A <= 1.00 )
Price = 10.95;
else if( A <= 2.625 )
Price = 12.95;
else if( A <= 4.15 )
Price = 14.95;
else if( A <= 10.00 )
Price = 18.95;
else
Price = 26.95;
}
//---------------------------------------------------------------------------
void TLabels::GetLabelCharacteristics(TLabelType& Label)
{
char LabelName[32], LabelColor[32];
int AdhesiveType;
int PrtType;
cout << "Enter the characteristics of the label\n";
cout << "Model Number: ";
cin >> Label.ModelNumber;
cout << "Type or Name: ";
gets(LabelName);
cout << "Label Color: ";
gets(LabelColor);
cout << "Adhesive Type"
<< "\n0 - No adhesive"
<< "\n1 - Removable Adhesive"
<< "\n2 - Non-Removable Adhesive"
<< "\nYour Choice: ";
cin >> AdhesiveType;
if( AdhesiveType == 1 )
Label.Adhesive = adRemovable;
else if( AdhesiveType == 2 )
Label.Adhesive = adNonRemovable;
else
Label.Adhesive = adNone;
cout << "Printing Type"
<< "\n1 - Inkjet"
<< "\n2 - Laser"
<< "\n3 - Multi-Purpose"
<< "\n4 - Unspecified"
<< "\nYour Choice: ";
cin >> Label.PrintType;
Label.Name = LabelName;
Label.Color = LabelColor;
}
//---------------------------------------------------------------------------
void TLabels::ShowReceipt(const TDimensions& Rect,
const TLabelType& Label)
{
TAdhesive Type = Label.getAdhesive();
cout << "=================================";
cout << "\n - Pacific Office Store -";
cout << "\n=================================";
cout << "\n Label Order - Receipt";
cout << "\n---------------------------------\n";
cout << "\n Dimensions: "
<< setiosflags(ios::fixed) << setprecision(2)
<< Rect.getLength() << " * " << Rect.getHeight();
cout << "\n Model No.: " << Label.getModelNumber();
cout << "\n Model Name: " << Label.getName();
cout << "\n Color: " << Label.getColor();
cout << "\n Adhesive: ";
if( Type == adRemovable )
cout << "Removable";
else if( Type == adNonRemovable )
cout << "Non-Removable";
else
cout << "None";
cout << "\n Print Type: " << Label.getPrintType();
cout << "\n Price: " << Price;
cout << "\n=================================";
}
//---------------------------------------------------------------------------
|
The composition of classes performed on our objects allows us now to process an order and display its receipt:
//---------------------------------------------------------------------------
#include <iomanip>
#include <conio.h>
using namespace std;
//---------------------------------------------------------------------------
#include "Labels.h"
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TLabels Label;
TDimensions Dim;
TLabelType Type;
cout << "Welcome to Pacific Office Store\n";
cout << "This machine allows you to create labels\nto the desired "
<< "dimensions and custom characteristics\n";
Label.GetLabelDimensions(Dim);
Label.GetLabelCharacteristics(Type);
system("cls");
Label.ShowReceipt(Dim, Type);
return 0;
}
//---------------------------------------------------------------------------
|
|
Combining Objects |
- To prepare a class that woud handle student and grade registration, add a new
class. Save it as GradeReport
- In the GradeReport.h file, create the foundation of the class as follows:
//---------------------------------------------------------------------------
#ifndef GradeReportH
#define GradeReportH
//---------------------------------------------------------------------------
class TGradeReport
{
public:
private:
};
//---------------------------------------------------------------------------
#endif
|
- Open the Students.h and declare a friend class as follows:
//---------------------------------------------------------------------------
#ifndef StudentsH
#define StudentsH
#include <iostream>
//---------------------------------------------------------------------------
enum TStudentGender { sgUnspecified, sgMale, sgFemale };
//---------------------------------------------------------------------------
class TStudents
{
friend class TGradeReport;
public:
. . .
private:
. . .
};
//---------------------------------------------------------------------------
#endif
|
- Open the Grades.h file and declare friend class as follows:
//---------------------------------------------------------------------------
#ifndef GradesH
#define GradesH
#include "Students.h"
//---------------------------------------------------------------------------
class TGrades
{
friend class TGradeReport;
public:
. . .
private:
. . .
};
//---------------------------------------------------------------------------
#endi
|
- To process the registration or the grades, instead of passing the class variables by reference as we have seen already, we will change a little bit by returning the class from the function that will need them (this allows us to test both techniques of returning an object). This is just another way to get the same information. To create the new class, change the content of the GradeReport.h file as follows:
//---------------------------------------------------------------------------
#ifndef GradeReportH
#define GradeReportH
#include <iostream>
#include "Students.h"
#include "Grades.h"
//---------------------------------------------------------------------------
struct TGradeInfo
{
int Level;
string MajorCode;
string MajorName;
};
//---------------------------------------------------------------------------
class TGradeReport
{
public:
TGradeReport();
~TGradeReport();
TStudents Registration();
TGrades GetGrades();
void ShowReport(const TStudents Student, const TGrades Grd);
private:
TGradeInfo LevelInfo;
};
//---------------------------------------------------------------------------
#endif
|
- To implement the new class, change the GradeReport.cpp as follows:
//---------------------------------------------------------------------------
#include <iomanip>
using namespace std;
#include "GradeReport.h"
//---------------------------------------------------------------------------
TGradeReport::TGradeReport()
{
}
//---------------------------------------------------------------------------
TGradeReport::~TGradeReport()
{
}
//---------------------------------------------------------------------------
TStudents TGradeReport::Registration()
{
TStudents Student;
int Gender;
cout << "Enter the student's information\n";
cout << "First Name: "; cin >> Student.FirstName;
cout << "Last Name: "; cin >> Student.LastName;
cout << "Day of Birth: "; cin >> Student.DayOfBirth;
cout << "Month of Birth: "; cin >> Student.MonthOfBirth;
cout << "Year of Birth: "; cin >> Student.YearOfBirth;
out << "Gender: ";
cout << "\n1 - Male"
<< "\n2 - Female"
<< "\n3 - Unspecified"
<< "\nYour Choice: ";
cin >> Gender;
Student.setGender(Gender);
cout << "Grade Level(6, 5, 4, etc): ";
cin >> LevelInfo.Level;
cout << "Major Code (A4, F1, G2, etc): ";
cin >> LevelInfo.MajorCode;
cout << "Major Name (Ex.: American Indian History, SocioMafia):\n";
getline(cin, LevelInfo.MajorName);
return Student;
}
//---------------------------------------------------------------------------
TGrades TGradeReport::GetGrades()
{
TGrades Grade;
double Language1, Language2, Hist, Geog, Chem, Soc,
Math, CompSc, Mor, Sport;
cout << "\nEnter Student Grades\n";
cout << "English: "; cin >> Grade.English;
cout << "2nd Language: "; cin >> Grade.SecondLng;
cout << "History: "; cin >> Grade.History;
cout << "Geography: "; cin >> Grade.Geography;
cout << "Chemistry: "; cin >> Grade.Chemistry;
cout << "Sociology: "; cin >> Grade.Sociology;
cout << "Mathematics: "; cin >> Grade.Math;
cout << "Comp Sciences: "; cin >> Grade.CompSc;
cout << "Morale: "; cin >> Grade.Morale;
cout << "Sports: "; cin >> Grade.Sports;
return Grade;
}
//---------------------------------------------------------------------------
void TGradeReport::ShowReport(const TStudents Student,
const TGrades Grade)
{
cout << "=======================================";
cout << "\nStudent Personal Information";
cout << "\nFull Name: "
<< Student.getFirstName() << " "
<< Student.getLastName();
cout << "\nDate of Birth: "
<< Student.getDayOfBirth() << "/"
<< Student.getMonthOfBirth() << "/"
<< Student.getYearOfBirth();
cout << "\nGender: " << Student.getGender();
cout << "\nGrade Level: " << LevelInfo.Level;
cout << "\nMajor: "
<< LevelInfo.MajorCode << ": "
<< LevelInfo.MajorName;
cout << "\n---------------------------------------";
cout << setiosflags(ios::fixed) << setprecision(2);
cout << "\n\tEnglish: " << Grade.getEnglish();
cout << "\n\t2nd Language: " << Grade.getSecondLng();
cout << "\n\tHistory: " << Grade.getHistory();
cout << "\n\tGeography: " << Grade.getGeography();
cout << "\n\tChemistry: " << Grade.getChemistry();
cout << "\n\tSociology: " << Grade.getSociology();
cout << "\n\tMathematics: " << Grade.getMath();
cout << "\n\tComp Sciences: " << Grade.getCompSc();
cout << "\n\tMorale: " << Grade.getMorale();
cout << "\n\tSports: " << Grade.getSports();
cout << "\n---------------------------------------";
cout << "\n\tTotal: " << Grade.CalcTotal()
<< "\tMean: " << Grade.CalcMean();
cout << "\n=======================================";
}
//---------------------------------------------------------------------------
|
- The main() function can be used simply to call the functions that can take of any needed transaction. As an example, change the Main.cpp file as follows:
//---------------------------------------------------------------------------
#include <iomanip>
using namespace std;
//---------------------------------------------------------------------------
#include "Grades.h"
#include "Students.h"
#include "GradeReport.h"
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TGradeReport Report;
TStudents Student;
TGrades Grade;
Student = Report.Registration();
Grade = Report.GetGrades();
system("cls");
Report.ShowReport(Student, Grade);
return 0;
}
//---------------------------------------------------------------------------
|
- Test the program:
- Return to your programming environment
The ability to use already created objects is one of the strengths of C++. If you have a ready made object, you can construct a new one using the existing properties. Inheritance is the ability to create an object using, or based on, another. The new or inherited object is also said to derive, or be derived from, the other object.
There are various ways you can inherit an object: using an operating system object, basing an object on an existing C++ one, or creating an object from a C++ Builder class. To start, you should define an object as complete as possible. This means that it should have functionality, valuable properties, and behaviors that other objects can use with little concerns as to how the object is built, but trusting that it can handle the desired behavior.
Creating the Parent Object |
|
We will create an object that others can inherit from. We will build a brick used in construction. A brick is known by its length, height, and width; but it also has a rectangular base. Therefore, let’s build the base first.The header file of TRectangle creates an object with its dimensions as follows:
//---------------------------------------------------------------------------
#ifndef RectangleH
#define RectangleH
//---------------------------------------------------------------------------
class TRectangle
{
public:
TRectangle(double L = 0.00, double H = 0.00);
TRectangle(const TRectangle& r);
~TRectangle();
void setLength(const double L);
void setHeight(const double H);
void setDimensions(const double L, const double H);
double getLength() const;
double getHeight() const;
double Perimeter() const;
double Area() const;
private:
double Length;
double Height;
};
//---------------------------------------------------------------------------
#endif
|
The source file defines the object with its constructors, provides access to its members and calculates the area of the base:
//---------------------------------------------------------------------------
using namespace std;
#include "Rectangle.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
TRectangle::TRectangle(double L, double H)
: Length(L), Height(H)
{
}
//---------------------------------------------------------------------------
TRectangle::TRectangle(const TRectangle& Rect)
: Length(Rect.Length), Height(Rect.Height)
{
}
//---------------------------------------------------------------------------
TRectangle::~TRectangle()
{
}
//---------------------------------------------------------------------------
void TRectangle::setLength(const double L)
{
Length = L;
}
//---------------------------------------------------------------------------
void TRectangle::setHeight(const double H)
{
Height = H;
}
//---------------------------------------------------------------------------
void TRectangle::setDimensions(const double L, const double H)
{
setLength(L);
setHeight(H);
}
//---------------------------------------------------------------------------
double TRectangle::getLength() const
{
return Length;
}
//---------------------------------------------------------------------------
double TRectangle::getHeight() const
{
return Height;
}
//---------------------------------------------------------------------------
double TRectangle::Perimeter() const
{
return 2 * (Length + Height);
}
//---------------------------------------------------------------------------
double TRectangle::Area() const
{
return Length * Height;
}
//---------------------------------------------------------------------------
|
To test the object, we will use the main() function. To make sure the object can respond, we test it with its default values. Then we supply its dimensions and display it. Finally, we make a copy of the object and test that copy.
//---------------------------------------------------------------------------
#include <iomanip>
using namespace std;
//---------------------------------------------------------------------------
#include "Rectangle.h"
//---------------------------------------------------------------------------
void RectProperties(const TRectangle& R)
{
cout << "Characteristics of the rectangle";
cout << setiosflags(ios::fixed) << setprecision(2);
cout << "\nLength: " << R.getLength();
cout << "\nHeight: " << R.getHeight();
cout << "\nPerimeter: " << R.Perimeter();
cout << "\nArea: " << R.Area();
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TRectangle Rect1;
double L = 12.125, H = 8.625; // Rectangle with default dimensions
TRectangle Rect2(L, H); // Rectangle with supplied dimensions
TRectangle Rect3; // Will be used to make/test a copy
cout << "Properties of the rectangle with default values";
RectProperties(Rect1);
cout << "\n\nRectangle with provided dimensions";
RectProperties(Rect2);
Rect3 = Rect2;
cout << "\n\nA copy of an existing rectangle";
RectProperties(Rect3);
return 0;
}
//---------------------------------------------------------------------------
|
|
Creating a Parent Object |
- Start a new C++ Console Application. Save the project in a folder called
People
- Save the file as Main and the project as Basis
- Add a new class and save it as Person
- To create a base class, change the header file as follows:
//---------------------------------------------------------------------------
#ifndef PersonH
#define PersonH
#include <iostream>
//---------------------------------------------------------------------------
class TPerson
{
public:
TPerson(string fn = "", string ln = "");
TPerson(const TPerson& P);
~TPerson();
void setFirstName(const string f);
string getFirstName() const;
void setLastName(const string l);
string getLastName() const;
private:
string FirstName;
string LastName;
};
//---------------------------------------------------------------------------
#endif
|
- Implement the source file as follows:
//---------------------------------------------------------------------------
using namespace std;
#include "Person.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
TPerson::TPerson(string fn, string ln)
: FirstName(fn), LastName(ln)
{
}
//---------------------------------------------------------------------------
TPerson::TPerson(const TPerson& P)
: FirstName(P.FirstName), LastName(P.LastName)
{
}
//---------------------------------------------------------------------------
TPerson::~TPerson()
{
}
//---------------------------------------------------------------------------
void TPerson::setFirstName(const string f)
{
FirstName = f;
}
//---------------------------------------------------------------------------
string TPerson::getFirstName() const
{
return FirstName;
}
//---------------------------------------------------------------------------
void TPerson::setLastName(const string l)
{
LastName = l;
}
//---------------------------------------------------------------------------
string TPerson::getLastName() const
{
return LastName;
}
//---------------------------------------------------------------------------
|
- To find out whether the new class work, change the Main.cpp file as follows:
//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
#include "Person.h"
//---------------------------------------------------------------------------
void ShowInfo(const TPerson& Pers)
{
cout << "\nFull Name: " << Pers.getFirstName()
<< " " << Pers.getLastName();
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TPerson P("John", "Landis");
cout << "Personal Information";
ShowInfo(P);
return 0;
}
//---------------------------------------------------------------------------
|
- Test the application and return to your programming environment.
Once you have a defined object, you can apply its behavior as the starting point of another object. The basic syntax on inheriting from an object is:
structORclass NewObject : AccessLevel ParentObject;
The word structORclass will be replaced by struct or class depending on the object type you are trying to create.
The NewObject element represents the name of the object you are creating.
The colon (:) is read “is based on”. It lets the compiler know that the new object gets its starting behavior and properties from another object.
The word AccessLevel specifies whether the object will use the public or private (or protected) level of access. The most common inheritance, which is also the most we will study, is the public inheritance. If you are creating an object whose parent is a structure, you can usually omit this access level because a structure is public by default. Otherwise, you should specify the level of access.
The ParentObject is the name of the object that the new object is based or is inheriting from.
When inheriting from another object, the new object is considered a child. To get the properties of the parent object, you should declare an instance of the parent. This instance will provide access to the members of the original object. The new object will not have access to the private members of the parent.
As we now have a good working rectangle, we will use it as the base of our brick. The header file of TBox creates an object whose base is the TRectangle object. |
|
//---------------------------------------------------------------------------
#ifndef BoxH
#define BoxH
#include "Rectangle.h"
//---------------------------------------------------------------------------
class TBox : public TRectangle
{
public:
TBox(double L = 0.00, double H = 0.00, double W = 0.00);
TBox(const TBox& B);
~TBox();
void setWidth(const double W);
void setDimensions(const double Length,
const double Height, const double Width);
double getWidth() const { return Width; }
double TotalArea() const;
double Volume() const;
private:
double Width;
};
//---------------------------------------------------------------------------
#endif
|
The source file is used to define the object. It makes sure that the new object has access to the desired properties of the parent. This is done using the access methods of the parent object called from the new constructors:
//---------------------------------------------------------------------------
using namespace std;
#include "Box.h"
//---------------------------------------------------------------------------
TBox::TBox(double L, double H, double W)
: TRectangle(L, H), Width(W)
{
}
//---------------------------------------------------------------------------
TBox::~TBox()
{
//TODO: Add your source code here
}
//---------------------------------------------------------------------------
void TBox::setWidth(const double W)
{
if( Width < 0.00 )
Width = 0.00;
else
Width = W;
}
//---------------------------------------------------------------------------
void TBox::setDimensions(const double L,
const double H, const double W)
{
setLength(L);
setHeight(H);
setWidth(W);
}
//---------------------------------------------------------------------------
double TBox::TotalArea() const
{
double Face1 = getLength() + getHeight();
double Face2 = getHeight() + getWidth();
double Face3 = getLength() + getWidth();
return (2 * Face1) + (2 * Face2) + (2 * Face3);
}
//---------------------------------------------------------------------------
double TBox::Volume() const
{
return getLength() * getHeight() * getWidth();
}
//---------------------------------------------------------------------------
|
To test the new object, we will use the main() function. First, we will declare a Box without arguments, which means we will display it with the default dimensions. Second, we will test the Box with supplied dimensions:
//---------------------------------------------------------------------------
#include <iomanip>
using namespace std;
//---------------------------------------------------------------------------
#include "Rectangle.h"
#include "Box.h"
//---------------------------------------------------------------------------
void RectProperties(const TRectangle& R)
{
. . .
}
//---------------------------------------------------------------------------
void BoxProperties(const TBox& B)
{
cout << "Characteristics of the box";
cout << setiosflags(ios::fixed) << setprecision(2);
cout << "\nLength: " << B.getLength();
cout << "\nHeight: " << B.getHeight();
cout << "\nWidth: " << B.getWidth();
cout << "\nArea: " << B.TotalArea();
cout << "\nVolume: " << B.Volume();
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TBox RedBox;
cout << "A Box with default values";
BoxProperties(RedBox);
cout << "\n\n";
TBox GrayBox(6.55, 5.25, 5.75);
cout << "Properties of the Box with dimensions";
BoxProperties(GrayBox);
return 0;
}
//---------------------------------------------------------------------------
|
The protected Access Level |
|
The TBox object we created based on the TRectangle class is not very impressive. For one thing, the TBox is using the same features as any other object in order to access the member variables of its parents. This does not provide any privileged access for a child of an object. C++ provides a solution to this problem: a special relationship between an inherited object and its parent.
In the past, we learned that the public level allows the client of a class to access any member of the public section of the class. We also learned to hide other members by declaring them in the private section, which prevents the clients of class from accessing such variables. You can create a special access level that allows only the children of a class to have access to certain members of the parent class. This new access level is called protected and created with that keyword.
The box we created and inherited from the TRectangle object needs to be able to initialize a parallelepiped rectangle with the length, height, and the self-added width. To allow this relationaship, you would change the TRectangle class as follows:
//---------------------------------------------------------------------------
#ifndef RectangleH
#define RectangleH
//---------------------------------------------------------------------------
class TRectangle
{
public:
TRectangle(double L = 0.00, double H = 0.00);
TRectangle(const TRectangle& r);
~TRectangle();
void setLength(const double L);
void setHeight(const double H);
void setDimensions(const double L, const double H);
double getLength() const;
double getHeight() const;
double Perimeter() const;
double Area() const;
protected:
double Length;
double Height;
};
//---------------------------------------------------------------------------
#endif
|
Since only the access level of the member variables has changed, nothing needs to be done in the implementation of the class. On the other hands, by making the member variables of the TRectangle class protected, the TBox class and its public members now have access to their parent’s protected members. This allows us the change the source file of the TBox object as follows:
//---------------------------------------------------------------------------
using namespace std;
#include "Box.h"
//---------------------------------------------------------------------------
TBox::TBox(double L, double H, double W)
: TRectangle(L, H), Width(W)
{
}
//---------------------------------------------------------------------------
TBox::TBox(const TBox& B)
: Width(B.Width)
{
Length = B.Length;
Height = B.Height;
}
//---------------------------------------------------------------------------
TBox::~TBox()
{
//TODO: Add your source code here
}
//---------------------------------------------------------------------------
void TBox::setWidth(const double W)
{
if( Width < 0.00 )
Width = 0.00;
else
Width = W;
}
//---------------------------------------------------------------------------
void TBox::setDimensions(const double L,
const double H, const double W)
{
setLength(L);
setHeight(H);
setWidth(W);
}
//---------------------------------------------------------------------------
double TBox::TotalArea() const
{
double Face1 = Length + Height;
double Face2 = Height + Width;
double Face3 = Length + Width;
return (2 * Face1) + (2 * Face2) + (2 * Face3);
}
//---------------------------------------------------------------------------
double TBox::Volume() const
{
return Length * Height * Width;
}
//---------------------------------------------------------------------------
|
As you can see, the derived class now has access to the member variables of the parent class and can use them to safely perform the needed calculations.
|
Inheriting Objects |
- To create a protected access level on the parent object, make the following change in the Person.h file:
//---------------------------------------------------------------------------
#ifndef PersonH
#define PersonH
#include <iostream>
//---------------------------------------------------------------------------
class TPerson
{
public:
TPerson(string fn = "", string ln = "");
TPerson(const TPerson& P);
~TPerson();
void setFirstName(const string f);
string getFirstName() const;
void setLastName(const string l);
string getLastName() const;
protected:
string FirstName;
string LastName;
private:
};
//---------------------------------------------------------------------------
#endif
|
- Add a new class and save it as Student
- To derive an object from another, change the header file as follows:
#define StudentH
#include "Person.h"
//---------------------------------------------------------------------------
class TStudent : public TPerson
{
public:
TStudent();
TStudent(string fn, string ln,
int DOB, int MOB, int YOB, int g);
TStudent(string fn, string ln);
TStudent(int DOB, int MOB, int YOB);
TStudent(const TStudent& S);
~TStudent();
void setDayOfBirth(const int d) { DayOfBirth = d; }
int getDayOfBirth() const { return DayOfBirth; }
void setMonthOfBirth(const int m) { MonthOfBirth = m; }
int getMonthOfBirth() const { return MonthOfBirth; }
void setYearOfBirth(const int y) { YearOfBirth = y; }
int getYearOfBirth() const { return YearOfBirth; }
void setGender(const int g) { Gender = g; }
string getGender() const;
private:
int DayOfBirth;
int MonthOfBirth;
int YearOfBirth;
int Gender;
};
//---------------------------------------------------------------------------
#endif
|
- To initialize the class using the constructor(s) of its base class, implement the new object as follows:
//---------------------------------------------------------------------------
using namespace std;
#include "Student.h"
//---------------------------------------------------------------------------
TStudent::TStudent()
: TPerson("John", "Doe"),
DayOfBirth(1),
MonthOfBirth(1),
YearOfBirth(1990),
Gender(0)
{
}
//---------------------------------------------------------------------------
TStudent::TStudent(string fn, string ln,
int DOB, int MOB, int YOB, int g)
: TPerson(fn, ln),
DayOfBirth(DOB), MonthOfBirth(MOB), YearOfBirth(YOB), Gender(g)
{
}
//---------------------------------------------------------------------------
TStudent::TStudent(string fn, string ln)
: TPerson(fn, ln), DayOfBirth(1), MonthOfBirth(1), YearOfBirth(1990)
{
}
//---------------------------------------------------------------------------
TStudent::TStudent(int DOB, int MOB, int YOB)
: TPerson("", ""), DayOfBirth(DOB), MonthOfBirth(MOB), YearOfBirth(YOB)
{
}
//---------------------------------------------------------------------------
TStudent::TStudent(const TStudent& Stud)
: TPerson(Stud.FirstName, Stud.LastName),
DayOfBirth(Stud.DayOfBirth), MonthOfBirth(Stud.MonthOfBirth),
YearOfBirth(Stud.YearOfBirth), Gender(Stud.Gender)
{
}
//---------------------------------------------------------------------------
TStudent::~TStudent()
{
}
//---------------------------------------------------------------------------
string TStudent::getGender() const
{
if( Gender == 1 )
return "Male";
else if( Gender == 2 )
return "Female";
else
return "Unspecified";
}
//--------------------------------------------------------------------------
|
- To prepare the program for a test, change the Main.cpp file as follows:
//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
#include "Student.h"
//---------------------------------------------------------------------------
void ShowInfo(const TStudent& S)
{
cout << "\nFull Name: " << S.getFirstName()
<< " " << S.getLastName();
cout << "\nDate of Birth: "
<< S.getDayOfBirth() << "/" << S.getMonthOfBirth()
<< "/" << S.getYearOfBirth();
cout << "\nGender: " << S.getGender();
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TStudent P;
P.setFirstName("Hermine");
P.setLastName("Akono");
P.setDayOfBirth(12);
P.setMonthOfBirth(5);
P.setYearOfBirth(1988);
P.setGender(2);
cout << "Personal Information";
ShowInfo(P);
return 0;
}
//---------------------------------------------------------------------------
|
- Implement the Student.cpp class as follows:
//---------------------------------------------------------------------------
using namespace std;
#include "Student.h"
//---------------------------------------------------------------------------
TStudent::TStudent()
: TPerson("John", "Doe"),
DayOfBirth(1),
MonthOfBirth(1),
YearOfBirth(1990),
Gender(0)
{
}
//---------------------------------------------------------------------------
TStudent::TStudent(string fn, string ln,
int DOB, int MOB, int YOB, int g)
: TPerson(fn, ln),
DayOfBirth(DOB), MonthOfBirth(MOB), YearOfBirth(YOB), Gender(g)
{
}
//---------------------------------------------------------------------------
TStudent::TStudent(string fn, string ln)
: TPerson(fn, ln),
DayOfBirth(1), MonthOfBirth(1), YearOfBirth(1990)
{
}
//---------------------------------------------------------------------------
TStudent::TStudent(int DOB, int MOB, int YOB)
: TPerson("", ""), DayOfBirth(DOB), MonthOfBirth(MOB), YearOfBirth(YOB)
{
}
//---------------------------------------------------------------------------
TStudent::TStudent(const TStudent& Stud)
: TPerson(Stud.FirstName, Stud.LastName),
DayOfBirth(Stud.DayOfBirth), MonthOfBirth(Stud.MonthOfBirth),
YearOfBirth(Stud.YearOfBirth), Gender(Stud.Gender)
{
}
//---------------------------------------------------------------------------
TStudent::~TStudent()
{
}
//---------------------------------------------------------------------------
string TStudent::getGender() const
{
if( Gender == 1 )
return "Male";
else if( Gender == 2 )
return "Female";
else
return "Unspecified";
}
//--------------------------------------------------------------------------
|
- To prepare a test, change the Main.cpp file as follows:
//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
#include "Student.h"
//---------------------------------------------------------------------------
void ShowInfo(const TStudent& S)
{
cout << "\nFull Name: " << S.getFirstName()
<< " " << S.getLastName();
cout << "\nDate of Birth: "
<< S.getDayOfBirth() << "/" << S.getMonthOfBirth()
<< "/" << S.getYearOfBirth();
cout << "\nGender: " << S.getGender();
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TStudent P;
P.setFirstName("Hermine");
P.setLastName("Akono");
P.setDayOfBirth(12);
P.setMonthOfBirth(5);
P.setYearOfBirth(1988);
P.setGender(2);
cout << "Personal Information";
ShowInfo(P);
return 0;
}
//---------------------------------------------------------------------------
|
- Test the program and return to your programming environment
The most common inheritance consists of an object deriving its foundation from another object. This is referred to as single inheritance. C++ allows an object to be based on more than one object. This is called refered to as multiple inheritance.
When an object is based on many other objects, it benefits from the variables of those objects. It has direct access to the public and protected members of each parent object.
To apply a multiple inheritance, specify each class on the right side of the : operator.
|
Performing Multiple Inheritance |
- Add a new class to your project and save it as Address
- In the Address.h file, create a TAddress class as follows:
//---------------------------------------------------------------------------
#ifndef AddressH
#define AddressH
#include <iostream>
//---------------------------------------------------------------------------
class TAddress
{
public:
TAddress(string a = "123 Main Street #A",
string c = "City Ville",
string s = "MD",
string z = "20900");
TAddress(const TAddress& d);
~TAddress();
void setAddress(const string a) { Address = a; }
string getAddress() const { return Address; }
void setCity(const string c) { City = c; }
string getCity() const { return City; }
void setState(const string s) { State = s; }
string getState() const { return State; }
void setZIPCode(const string z) { ZIPCode = z; }
string getZIPCode() const { return ZIPCode; }
protected:
string Address;
string City;
string State;
string ZIPCode;
};
//---------------------------------------------------------------------------
#endif
|
- Implement the TAddreass class as follows:
//---------------------------------------------------------------------------
using namespace std;
#include "Address.h"
//---------------------------------------------------------------------------
TAddress::TAddress(string a, string c, string s, string z)
: Address(a), City(c), State(s), ZIPCode(z)
{
}
//---------------------------------------------------------------------------
TAddress::TAddress(const TAddress& d)
: Address(d.Address), City(d.City), State(d.State), ZIPCode(d.ZIPCode)
{
}
//---------------------------------------------------------------------------
TAddress::~TAddress()
{
}
//---------------------------------------------------------------------------
|
- Add a new class and save it as Staff
- To perform a multiple inheritance, in the Staff.h file, create a TStaff class as follows:
//---------------------------------------------------------------------------
#ifndef StaffH
#define StaffH
#include <iostream>
#include "Person.h"
#include "Address.h"
//---------------------------------------------------------------------------
class TStaff : public TPerson, public TAddress
{
public:
TStaff();
TStaff(string fn, string ln,
string a, string c, string s, string z,
double L, char e, int m);
TStaff(const TStaff& S);
~TStaff();
void setSalary(const double s) { Salary = s; }
double getSalary() const;
void setEmplStatus(const char e) { EmploymentStatus = e; }
string getEmploymentStatus() const;
void setMaritalStatus(const int m) { MaritalStatus = m; }
string getMaritalStatus() const;
protected:
double Salary;
char EmploymentStatus;
int MaritalStatus;
};
//---------------------------------------------------------------------------
#endif
|
- Implement the TStaff class as follows:
//---------------------------------------------------------------------------
using namespace std;
#include "Staff.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
TStaff::TStaff()
{
}
//---------------------------------------------------------------------------
TStaff::TStaff(string fn, string ln,
string a, string c, string s, string z,
double L, char e, int m)
: TPerson(fn, ln),
TAddress(a, c, s, z),
Salary(L), EmploymentStatus(e), MaritalStatus(m)
{
}
//---------------------------------------------------------------------------
TStaff::TStaff(const TStaff& S)
: Salary(S.Salary),
EmploymentStatus(S.EmploymentStatus),
MaritalStatus(S.MaritalStatus)
{
}
//---------------------------------------------------------------------------
TStaff::~TStaff()
{
}
//---------------------------------------------------------------------------
double TStaff::getSalary() const
{
if( Salary < 12.42 )
return 12.42;
else
return 12.42;
}
//---------------------------------------------------------------------------
string TStaff::getEmploymentStatus() const
{
string EStatus;
switch(EmploymentStatus)
{
case 'f':
case 'F':
EStatus = "Full-Time";
break;
case 'p':
case 'P':
EStatus = "Parti-Time";
break;
case 'c':
case 'C':
EStatus = "Contractor";
break;
case 's':
case 'S':
EStatus = "Seasonal";
break;
default:
EStatus = "Unknown";
}
return EStatus;
}
//---------------------------------------------------------------------------
string TStaff::getMaritalStatus() const
{
string MStatus;
switch(MaritalStatus)
{
case 1:
MStatus = "Single";
break;
case 2:
MStatus = "Married";
break;
case 3:
MStatus = "Widow";
break;
case 4:
MStatus = "Divorcé";
break;
default:
MStatus = "Not Specified";
}
return MStatus;
}
//---------------------------------------------------------------------------
|
- Change the Main.cpp file as follows:
//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
#include "Staff.h"
//---------------------------------------------------------------------------
void ShowInfo(const TStaff& S)
{
cout << "\nFull Name: " << S.getFirstName()
<< " " << S.getLastName();
cout << "\nAddress: " << S.getAddress()
<< "\n " << S.getCity() << " "
<< S.getState() << " " << S.getZIPCode();
cout << "\nEmployment: " << S.getEmploymentStatus();
cout << "\nSalary: $" << S.getSalary();
cout << "\nMarital St: " << S.getMaritalStatus();
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TStaff Empl;
Empl.setFirstName("Mark");
Empl.setLastName("Azzuri");
Empl.setAddress("12432 Lockwood Drive #D12");
Empl.setCity("Hyattsville");
Empl.setState("MD");
Empl.setZIPCode("20740");
Empl.setSalary(18.05);
Empl.setEmplStatus('F');
Empl.setMaritalStatus(1);
cout << "Personal Information";
ShowInfo(Empl);
return 0;
}
//---------------------------------------------------------------------------
|
- Test the program and return to your programming environment
- To allow the user to process hiring, change the Main.cpp file as follows:
//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
#include "Staff.h"
//---------------------------------------------------------------------------
void NewEmployee(TStaff& Employee)
{
string FirstName, LastName, Address, City, State, ZIPCode;
double Salary;
char EmplStatus;
int MStatus;
cout << "First Name: "; cin >> FirstName;
cout << "Last Name: "; cin >> LastName;
cout << "Address: "; getline(cin, Address);
cout << "City: "; getline(cin, City);
cout << "State: "; getline(cin, State);
cout << "ZIP Code: "; cin >> ZIPCode;
cout << "Hourly Salary: $"; cin >> Salary;
cout << "Employment Status"
<< "\nf - Full-Time"
<< "\np - Part-Time"
<< "\nc - Contractor"
<< "\ns - Seasonal"
<< "\nYour Choice: "; cin >> EmplStatus;
cout << "Marital Status"
<< "\n1 - Single"
<< "\n2 - Married"
<< "\n3 - Widow"
<< "\n4 - Divorcé"
<< "\nStatus: "; cin >> MStatus;
Employee.setFirstName(FirstName);
Employee.setLastName(LastName);
Employee.setAddress(Address);
Employee.setCity(City);
Employee.setState(State);
Employee.setZIPCode(ZIPCode);
Employee.setSalary(Salary);
Employee.setEmplStatus(EmplStatus);
Employee.setMaritalStatus(MStatus);
}
//---------------------------------------------------------------------------
void ShowInfo(const TStaff& S)
{
cout << "\nFull Name: " << S.getFirstName()
<< " " << S.getLastName();
cout << "\nAddress: " << S.getAddress()
<< "\n " << S.getCity() << " "
<< S.getState() << " " << S.getZIPCode();
cout << "\nEmployment: " << S.getEmploymentStatus();
cout << "\nSalary: $" << S.getSalary();
cout << "\nMarital St: " << S.getMaritalStatus();
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
TStaff Empl;
cout << "Enter information about the new hire\n";
NewEmployee(Empl);
system("cls");
cout << "Personal Information";
ShowInfo(Empl);
return 0;
}
//---------------------------------------------------------------------------
|
- Test the program and return to your programming environment.
|
|