![]() |
Introduction to Classes |
|
Programmer-Defined Objects |
|
The data types we have applied so far to our variables were used to identify individual items. To create more advanced and complete objects, C++ allows you to group these identifiers and create a newly defined object. |
|
Introduction |
|
An object, such as a CD Player, a printer, a car, etc, is built from assembling various parts. In the same way, C++ allows you to group various variables and create a new object called a class. Imagine a company that manufactures shoe boxes hires you to write a program that would help design and identify those shoe boxes. A shoe box is recognized for its dimensions (length, width, height), color, and shoe size that a particular box can contain, etc. The variables that characterize such an object could be: double Length, Width, Height; And the program that defines a shoe box object could be: |
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
// Define the characteristics of a shoe box
// The following characteristics are COMPLETELY random
double Length(12.55), Width(6.32), Height(8.74);
string Color("Yellow Stone");
float ShoeSize = 10.50;
// Display the characteristics of the shoe box
cout << "Characteristics of this shoe box";
cout << setiosflags(ios::fixed) << setprecision(2);
cout << "\n\tLength = " << Length << "\n\tWidth = " << Width
<< "\n\tHeight = " << Height << "\n\tVolume = " << Length * Width * Height
<< "\n\tColor = " << Color << "\n\tSize = " << ShoeSize << "\n\n";
return 0;
}
|
The program would produce:
Characteristics of this shoe box Length = 12.55 Width = 6.32 Height = 8.74 Volume = 693.22 Color = Yellow Stone Size = 10.50 Press any key to continue... Unless dealing with one shoe box, this program would be rudimentary to run for each object. The solution is to create an object called box that groups everything that characterizes the object. |
|
Creating a Class |
|
To create a class, use the class keyword followed by a name for the object. Like any other declared variable, the class declaration ends with a semi-colon. The name of a class follows the rules we have applied so far for variable and function names. To declare a class called ShoeBox, you would type the following: class ShoeBox; As a name that represents a group of items, a class has a body that would be used to define the items that compose it. The body of a class starts with an opening curly bracket "{" and ends with a closing one "}". Therefore, another way to create a class is: class ClassName{}; This could also be created as: class ClassName { or class ClassName Either of these techniques produces the same effect. Since a class is built from combining other identifiers, you will list each variable inside of the body of the class. Each item that composes the class is represented as a complete variable declared with a data type and a name. As a variable, each declaration must end with a semi-colon. Continuing with our shoe box object, you could create it using the class as follows: class ShoeBox
{
double Length, Width, Height;
char Color[12];
float ShoeSize;
};
The items that compose a class are called members of the class. |
|
Accessing a Class |
|
A common object in real life is visibly made of two categories of parts: those you can see or touch and those you do not have access to. The parts you can see or touch are considered visible or accessible. In C++, such parts are referred to as public. Those you cannot see or touch are considered hidden. In C++, such parts are referred to as private. Like objects in real life, a class is made of sections that the other functions or other objects cannot “see” and those the other objects can access. The other objects of of the program are sometimes referred to as the clients of the object. The parts the client of an object can touch in a class are considered public and the others are private. When creating a class, you will define which items are public and which ones are private. The items that are public are created in a section that starts with the public keyword followed by a semi-colon. The others are in the private section. If you do not specify these sections, all of the members of a class are considered private. For example, all of the members of the previously defined ShoeBox class are private. Using the public and private sections, our shoe box object can be created as: |
class ShoeBox
{
public:
double Length, Width, Height;
string Color;
private:
float ShoeSize;
};
|
|
The public and private keywords are referenced by their access level because they control how much access a variable allows. You can create as many public sections or as many private sections as you want. For example, the above class could be created as: |
class ShoeBox
{
public:
double Length, Width, Height;
public:
string Color;
double Volume;
private:
float ShoeSize;
private:
char Material;
string Color;
};
|
|
When creating a class with different public and private sections, all of the declared variables under an access level keyword abide by the rules of that access level. The fact that you use different public sections does not by any means warrant different public levels to the variables. A variable declared as public in one public section has the same public level of access as any other variable that is declared in another public section. A variable that is declared in a class is called a member of the class. Once the class has been defined, you can use it as an individual variable. |
|
Declaring a Class |
|
After defining a class, you can declare it as a variable using the same syntax we have used for any other variable. A class is declared using its name followed by a name for the defined variable and ending with a semi-colon. For example, our ShoeBox class can be declared as follows: ShoeBox Shake; When an object has been declared, you can access any of its members using the member access operator ".". First, type the name of the object variable, followed by a period, followed by the name of the member you want to access. For example, to access the member Length of the above class, you would write: Shake.Length; Using this syntax, you can display the value of a class member: cout << Shake.Length; or you can request its value from the user, using the cin operator. Here is an example: cin >> Shake.Lengh;
Using the cout extractor to display the values of the object members, our program could be as follows: |
#include <iostream>
#include <string>
using namespace std;
class ShoeBox
{
public:
double Length, Width, Height;
string Color;
private:
float ShoeSize;
};
int main()
{
ShoeBox Shake; // Display the characteristics of the shoe box
cout << "Characteristics of this shoe box";
cout << "\n\tLength = " << Shake.Length
<< "\n\tWidth = " << Shake.Width
<< "\n\tHeight = " << Shake.Height
<< "\n\tVolume = " << Shake.Length * Shake.Width * Shake.Height
<< "\n\tColor = " << Shake.Color
<< "\n\tSize = " << Shake.ShoeSize
<< "\n\n";
return 0;
}
|
|
At this time, because of trying to access a private member, the program would produce the following error [C++ Error] Unit1.cpp(30): E2247 'ShoeBox::TShoeSize' is not accessible Even if you change the ShoeSize member access from private to public, the program would render unpredictable results because the members have not been given appropriate values:
Characteristics of this shoe box Length = 0 Width = 1.79571e-307 Height = 4.17266e-315 Volume = 0 Color = Size = 3.58732e-43Press any key to continue... |
|
Techniques of Initializing a Class |
|
There are various techniques used to initialize a class: initializing individual members or initializing the class as a whole.
To initialize a member of a class, access it and assign it an appropriate value. |
#include <iostream>
#include <string>
using namespace std;
class ShoeBox
{
public:
double Length, Width, Height;
string Color;
float ShoeSize;
private:
};
int main()
{
ShoeBox Shake;
double Volume; // Initializing each member of the class
Shake.Length = 12.55;
Shake.Width = 6.32;
Shake.Height = 8.74;
Shake.Color = "Yellow Stone";
Shake.ShoeSize = 10.50;
Volume = Shake.Length * Shake.Width * Shake.Height;
// Display the characteristics of the shoe box
cout << "Characteristics of this shoe box";
cout << "\n\tLength = " << Shake.Length
<< "\n\tWidth = " << Shake.Width
<< "\n\tHeight = " << Shake.Height
<< "\n\tVolume = " << Volume
<< "\n\tColor = " << Shake.Color
<< "\n\tSize = " << Shake.ShoeSize << "\n\n";
return 0;
}
|
|
This time, the program would render a reasonable result. You can also initialize an object as a variable. This time, type the name of the variable followed by the assignment operator, followed by the desired values of the variables listed between an opening and a closing curly brackets; each value is separated with a comma. The first rule you must keep in mind is that the list of variables must follow the order of the declared members of the class. The second rule you must observe is that none of the members of the class must be another class. In the following example, one of the members of the class is another class, namely a string. Because of the way a variable of the class is declared, the program would not compile: |
#include <iostream>
#include <string>
using namespace std;
class ShoeBox
{
public:
double Length, Width, Height;
string Color;
float ShoeSize;
private:
};
int main()
{
// Declaring and initializing the class as a variable
ShoeBox LadyShake = { 12.55, 6.32, 8.74, "Yellow Stone", 10.50 };
Double Volume = LadyShake.Length * LadyShake.Width * LadyShake.Height;
// Display the characteristics of the shoe box
cout << "Characteristics of this shoe box";
cout << "\n\tLength = " << LadyShake.Length
<< "\n\tWidth = " << LadyShake.Width
<< "\n\tHeight = " << LadyShake.Height
<< "\n\tVolume = " << Volume
<< "\n\tColor = " << LadyShake.Color
<< "\n\tSize = " << LadyShake.ShoeSize << "\n\n";
return 0;
}
|
|
Classes and Member Functions |
|
The primary motivation of using classes in a program is to create objects as complete as possible. An object must be able to handle its own business so that the other objects of the program or of another program would only need to know which object can take care of a particular need they have. A regular variable, as a member of an object, cannot handle assignments; this job is handled by particular functions declared as members of a class. A function as a member of a class is also called a Method. In this book, the words “method” and “function”, when associated with a class, will refer to the same thing: a member function of the class. |
|
Declaring Member Functions |
|
A member function is declared like any of the functions we have used so far; it could or could not return a value. The shoe box we have been using so far needs a volume that would be used to determine what size can fit in the box. Therefore, we will use a member function that can perform that calculation. Our object, when including methods could be structured as follows: |
class ShoeBox
{
public:
double Length;
double Width;
double Height;
string Color;
float ObtainShoeSize();
double CalcVolume();
private:
};
|
|
When using functions on a class, the variables are used to hold or store values, called data, of the object, while member functions are used to perform assignments as related to the objects. One way you can control the data held by variables is to hide data from the "external world". To achieve this, you should declare the member variables in the private section. After doing this, use the methods in the public section to help the class interact with the other objects or functions of the program. At this time, our ShoeBox object would look like this: |
class ShoeBox
{
public:
float ObtainShoeSize();
double CalcVolume();
string Color;
private:
double Length;
double Width;
double Height;
};
|
|
There are at least two techniques you can use to implement a method member |
|
Implementing Member Functions Locally |
|
To implement a method in the class where it is declared, use the same techniques we used to define regular functions. When a method is a class' member, it has access to the member variables of the same class; this means you do not need to pass the variables as arguments (there are cases when you will need to); you can just use any of them as if it were supplied. Here is how you would define the
CalcVolume() method inside of the ShoeBox class: |
#include <string>
using namespace std;
class ShoeBox
{
public:
float ObtainShoeSize();
double CalcVolume()
{
return (Length * Width * Height);
}
string Color;
private:
double Length;
double Width;
double Height;
};
|
|
If your class has a lot of methods, this technique could be cumbersome. You should use it only for small methods. |
|
Implementing Member Functions Globally |
|
When the methods execute long assignments, you should implement them outside of the object by first accessing the desired function member of the class. To access a method of a class when implementing it, instead of the member access operator “.”, you will use the scope resolution operator represented as two colons :: To implement a method outside of the class, type the return value of the method, followed by the class' name, followed by the scope resolution operator “::”, followed by the method's name, followed by the arguments, if any, between parentheses, and finally define what the function should do, in its body.
Another implementation of our CalcVolume() method would be: |
class ShoeBox
{
public:
float ObtainShoeSize();
double CalcVolume();
string Color;
private:
double Length;
double Width;
double Height;
};
double ShoeBox::CalcVolume()
{
return (Length * Width * Height);
}
|
|
Inline Methods |
|
When studying functions, we learned that an assignment can be carried where it is being called. The same process can apply to a class’ member. To declare a class’ method as inline, precede its name with the inline keyword when declaring the method in the class: |
class ShoeBox
{
public:
inline Double CalcVolume();
float CalcShoeSize();
void Display();
private: . . .
};
|
|
You can choose which methods would be inline and which ones would not. When implementing the method, you can precede the method with the inline keyword. You can also omit the inline keyword in the class but use it when defining the method.
If you decide to implement a method locally (in the class), you have the option of implementing it as inline: |
class ShoeBox
{
public:
inline double CalcVolume()
{
return Length * Width * Height;
}
inline float CalcShoeSize()
{
return Length - 0.35;
}
void Display();
private:
double Length;
double Width;
double Height;
string Color;
};
|
|
On the other hand, if you omit the inline keyword, the C++ compiler would take care of it. Normally, any function implemented in the body of the class is considered inline. |
|
Class Members Interactions |
|
Regardless of how the member methods of an object are implemented, any method can call another without using an access operator. This allows an object’s methods to exchange information among themselves easily. Furthermore, unlike regular functions where a function must be declared prior to another function calling it, the method members of a class do not abide by that rule: one method can call another method before or after the other has been implemented, as long as it is defined somewhere. |
#include <iostream>
#include <string>
using namespace std;
class ShoeBox
{
public: . . .
};
void ShoeBox::Display()
{
// Initializing the dimensions
Length = 12.55;
Width = 6.32;
Height = 8.74;
Color = "Early Breeze";
// Display the characteristics of the shoe box
cout << "Characteristics of this shoe box";
cout << "\n\tLength = " << Length
<< "\n\tWidth = " << Width
<< "\n\tHeight = " << Height
<< "\n\tVolume = " << CalcVolume()
<< "\n\tColor = " << Color
<< "\n\tSize = " << CalcShoeSize();
}
duble ShoeBox::CalcVolume()
{
return Length * Width * Height;
}
|
|
Once an object is defined and behaves as complete as possible, the other function or objects of the program can make the appropriate calls trusting that the called object can handle its assignments efficiently. This ability allows you to (tremendously) reduce the work overload of the other components of a program. |
int main()
{
ShoeBox Sample;
Sample.Display();
return 0;
}
|
|
Tuning Objects |
|
There are other features you can apply to make your objects more professional and less prone to errors. These include constant arguments, constant, private,
and inline methods, etc. |
|
Constant Arguments |
|
When studying functions, we learned that when a function receives an argument that it does not modify, the argument should be declared as constant. This allows the compiler to make sure the argument would not be modified. The same technique applies to an argument used by a method of an object. |
double Area(Double Side1, Double Side2); |
|
After declaring it in the public section, we would define it as follows: |
double ShoeBox::Area(Double Side1, Double Side2)
{
return Side1 * Side2;
}
|
|
In the Display() method, we could display the area of the length by the height using: |
double ShoeBox::Area(const Double Side1, const Double Side2)
{
return Side1 * Side2;
}
|
|
For an example such as this one, the const keyword can be typed before or after the data type, the result would be the same. If a method is receiving more than one argument, their constancy is independent: the fact that one of them needs to be constant does not imply anything about the
other(s). |
void ShoeBox::Area(const Double S1, const Double S2, PChar n)
{
cout << "\nThe area of the " << n << " side is: " << S1 * S2;
}
|
|
In the Display() method, we could specify the name of the side and provide the corresponding measures as follows: Area(Length, Height, "front");Area(Length, Width, "top");Area(Width, Height, "left"); Here is the complete implementation: |
#include <iostream>
#include <string>
using namespace std;
class ShoeBox
{
public:
double CalcVolume()
{
return Length * Width * Height;
}
void Area(const double Side1, const double Side2, char SideName[]);
float CalcShoeSize()
{
return Length - 0.35;
}
void Display();
private:
double Length;
double Width;
double Height;
char Color[32];
};
void ShoeBox::Area(const double S1, const double S2, char N[])
{
cout << "\nThe area of the " << N << " side is: " << S1 * S2;
}
void ShoeBox::Display()
{
// Initializing the dimensions
Length = 10.42;
Width = 5.28;
Height = 5.88;
Color = "Yellow Stone";
// Display the characteristics of the shoe box
cout << "Characteristics of this shoe box";
cout << "\nDimensions(L*H*W) = "
<< Length << " * " << Height << " * " << Width;
Area(Length, Height, "front");
Area(Length, Width, "top");
Area(Height, Width, "left");
cout << "\n\tVolume = " << CalcVolume()
<< "\n\tColor = " << Color
<< "\n\tSize = " << CalcShoeSize();
}
int main()
{
ShoeBox Bambou;
Bambou.Display();
return 0;
}
|
|
Constant Methods |
|
Some of the method members of an object, though using member variables of the same object, do not modify them. To make sure that such a method does not alter the value of a member variable, the method should be declared and implemented as constant. To declare a method as a constant, add the const keyword to the right side of the method when declaring it. Here is an example: string SpecFullName() const; The CalcVolume() and the CalcShoeSize() methods do not modify the member variables they receive. You can reinforce this by declaring them as const: double CalcVolume() const;float CalcShoeSize() const;
When implementing the method, type the const keyword on the right side of the method’s closing parenthesis: |
double ShoeBox::CalcVolume() const
{
return Length * Width * Height;
}
float ShoeBox::CalcShoeSize() const
{
return Length - 0.35;
}
|
|
If you decide to define constant methods locally (inline), the only difference is to remove the semi-colon of the end of the declaration and define the method normally.
Notice that the Display() method assigns values to the member variables, which means it alters their values. Therefore, it cannot be declared or defined as constant. Here is the new version of our ShoeBox object: |
class ShoeBox
{
public:
double CalcVolume() const
{
return Length * Width * Height;
}
void Area(const double Side1, const double Side2, char SideName[]);
float CalcShoeSize() const
{
return Length - 0.35;
}
void Display();
private:
double Length;
double Width;
double Height;
string Color;
};
|
|
The program would still produce the same result. |
|
Private Methods |
|
At this time, we know that one of the responsibilities of a member method of an object is to carry assignments. Another job performed by methods is to communicate with the clients of an object. As you might have found out, some of the methods of an object are exclusively used to carry assignments. The external functions or other objects do not call such methods and do not communicate with them. If you create a class and know that a particular member method is not used to transfer data to the client methods, you can declare such a method as private, just like you would do with a member variable. |
class Employee
{
public:
void IdentifyEmployee();
string FullName() const { return FirstName + " " + LastName; }
void GetHourlySalary();
void CalcTotalHours();
void Display();
void CalcNetPay()
{
if( IsMarried() == false )
NetPay = GrossPay - (GrossPay * 30 / 100);
else
NetPay = GrossPay;
}
private:
void CalcGrossPay();
bool inline IsMarried() const;
string FirstName;
string LastName;
double TotalHours;
double HourlySalary;
double WeeklySalary;
double GrossPay;
double NetPay;
};
|
|
Objects and Their Implementations |
|
An object is made of the material that compose it and the actual structure of the object, which defines how the object is built and used. This means, a class is be made of two parts: its building block and its definition. These two parts of a class can be kept in different files that have access to each other. |
|
Class' Header File |
|
The building block or foundation of an class is made of the class' creation, listing all of its members. This foundation is created in a file called a header file, similar to the one we learned when studying functions. The name of the file follows the naming rules we have applied so far. The header file has an extension of .h. |
#include <iostream>
#include <string>
using namespace std;
class ShoeBox
{
public:
double CalcVolume() const
{
return Length * Width * Height;
}
void Area(const double Side1, const double Side2, char SideName[32]);
float CalcShoeSize() const
{
return Length - 0.35;
}
void Display();
private:
double Length;
double Width;
double Height;
string Color;
};
|
|
Class Source Code |
|
This file used to implement the object is called a source file. It is used to define what the object is supposed to do. It contains all or some of the methods and their implementations. To create the source file, from the New property page of the New Items dialog box, click the Cpp File icon and click OK. By default, the (first) file is called File1.cpp. To change that name, you must save the project and replace the name of the file with the desired name. A source file should at least start with a line that specifies the name of the header file that it is implementing. Since this file is usually created in the same project, it is specified with an include line that is encloses the file name with double-quotes. An example would be: #include "Book.h"
The main area of the file is made of the class' implementation. Here is what the source file of our ShoeBox would look like: |
#include "File1.h"
void ShoeBox::Area(const Double S1, const Double S2, PChar N)
{
cout << "\nThe area of the " << N << " side is = " << S1 * S2;
}
void ShoeBox::Display()
{
// Initializing the dimensions
Length = 14.32;
Width = 8.36;
Height = 6.54;
Color = "Brown Carpet";
// Display the characteristics of the shoe box
cout << "Characteristics of this shoe box";
cout << "\nDimensions(L*H*W) = "
<< Length << " * " << Height << " * "
<< Width; Area(Length, Height, "front");
Area(Length, Width, "top");
Area(Height, Width, "left");
cout << "\n\tVolume = " << CalcVolume()
<< "\n\tColor = " << Color
<< "\n\tSize = " << CalcShoeSize();
}
|
|
The main() function of our shoe box project is reduced to simply calling the appropriate ShoeBox method member: |
#include <iostream.h>
#include "ShoeBox.h"
int main()
{
ShoeBox Sala;
Sala.Display();
return 0;
}
|
|
|
||
| Previous | Copyright © 2000-2003 FunctionX, Inc. | Next |
|
|
||