Starting from this Module, you have to be careful for the source codes thatspan more than one line. When you copy and paste to the text or compiler editor, make it in one line! This Module is a transition from C to C++ and Topics of C++ such asFunctions,Arrays,Pointers andStructure that have been discussed in C Tutorial, will not be repeated. They are reusable! This Module and that follows can be a very good fundamental for Object Oriented programming though it is an old story:o). The source code is available inC++ Encapsulation source code.
| 12.1 Introduction
12.2 Starting With struct
// a struct data type struct item { int keep_data; };
item John_cat, Joe_cat, Big_cat;
// assigningvalues John_cat.keep_data = 10; Joe_cat.keep_data = 11; Big_cat.keep_data = 12;
|
1. // program start.cpp
2. #include <iostream>
3. using namespace std;
4.
5. struct item // a struct data type
6. {
7. int keep_data;
8. };
9.
10. void main()
11. {
12. item John_cat, Joe_cat, Big_cat;
13. int garfield; // a normal variable
14.
15. John_cat.keep_data = 10; // assigning values
16. Joe_cat.keep_data = 11;
17. Big_cat.keep_data = 12;
18. garfield = 13;
19.
20. // displaying data
21. cout<<"Data value for John_cat is "<<John_cat.keep_data<<"\n";
22. cout<<"Data value for Joe_cat is "<<Joe_cat.keep_data <<"\n";
23. cout<<"Data value for Big_cat is "<<Big_cat.keep_data<<"\n";
24. cout<<"Data value for garfield is "<<garfield<<"\n";
25. cout<<"Press Enter key to quit\n";
26. // system("pause");
27. }
Next, please refer to example program class.cpp. This program is identical to the last one except for a few program portions.
The first difference is that we have a class instead of a structure beginning in line 7.
class item
The only difference between a class and a structure is that a class begins with a private section by default whereas a structure begins with apublic section. The keywordclass is used to declare a class as illustrated.
The class named item is composed of the single variable named keep_data and two functions, set() andget_value().
A more complete definition of a class is: a group of variables (data), and one or more functions that can operate on that data.
In programming language terms, attributes, behaviors or properties of the object used for the member variables.
1. // program class.cpp using class instead of struct
2. #include <iostream>
3. using namespace std;
4.
5. // the class declaration part
6.
7. class item
8. {
9. int keep_data; // private by default, it is public in struct
10. public: // public part
11. void set(int enter_value);
12. int get_value(void);
13. };
14.
15. // class implementation part
16.
17. void item::set(int enter_value)
18. {
19. keep_data = enter_value;
20. }
21. int item::get_value(void)
22. {
23. return keep_data;
24. }
25.
26. // main program
27. void main()
28. {
29. item John_cat, Joe_cat, Big_cat;
30. // three objects instantiated
31. int garfield; // a normal variable
32.
33. John_cat.set(10); // assigning values
34. Joe_cat.set(11);
35. Big_cat.set(12);
36. garfield = 13;
37. // John_cat.keep_data = 100;
38. // Joe_cat.keep_data = 110;
39. // these are illegal cause keep_data now, is private by default
40.
41. cout<<"Accessing data using class\n";
42. cout<<"-------------------------\n";
43. cout<<"Data value for John_cat is "<<John_cat.get_value()<<"\n";
44. cout<<"Data value for Joe_cat is "<<Joe_cat.get_value()<<"\n";
45. cout<<"Data value for Big_cat is "<<Big_cat.get_value()<<"\n";
46. cout<<"\nAccessing data normally\n";
47. cout<<"---------------------------\n";
48. cout<<"Data value for garfield is "<<garfield<<"\n";
49.
50. // system("pause");
51. }
All data at the beginning of a class defaults to private and the private keyword is optional. This means, the data at the beginning of the class cannot be accessed from outside of the class; it is hidden from any outside access.
Therefore, the variable named keep_data which is part of the object named John_cat defined in line 37 and 38, is not available for use anywhere in the main() program. That is why we have to comment out the following codes:
// John_cat.keep_data = 100;
// Joe_cat.keep_data = 110;
It is as if we have built a wall around the variables to protect them from accidental corruption by outside programming influences.
The concept is graphically shown in figure 12.1, item class with its wall built around the data to protect it.
You will notice the small peep holes (through the arrow) we have opened up to allow the user to gain access to the functions set() and get_value(). The peep holes were opened by declaring the functions in the public section of the class.
12.3.2 Public Section
public: // public part
|
void item::set(int enter_value)
{
keep_data = enter_value;
}
int item::get_value(void)
{
return keep_data;
}
These two function definitions are called the implementation of the functions. The class name is required because we can use the same function name in other classes and the compiler will know with which class to associate each function implementation.
Notice that, the private data contained within the class is available within the implementation of the member functions of the class for modification or reading in the normal manner.
You can do anything with the private data within the function implementations which are a part of that class; also the private data of other classes is hidden and not available within the member functions of this class.
This is the reason we must prepend the class name to thefunction names of this class when defining them. Figure 12.2 depicts the data space following the program execution.
It is legal to declare variables and functions in the private part, and additional variables and functions in the public part also.
In most practical situations, variables only declared in the private section and functions only declared in the public part of a class definition. Occasionally, variables or functions are declared in the other part. This sometimes leads to a very practical solution to a particular problem, but in general, the entities are used only in the places mentioned for consistency and good programming style.
A variable with class scope is available anywhere within the scope of a class, including the implementation code, and nowhere else. Hence, the variable namedkeep_data has a class scope.
The following is a list of terminologies that you need to understand their meaning in object oriented programming for this tutorial discussion.
Term | Description |
class | Is a group of data and methods (functions). A class is very much like a structure type as used in ANSI-C, it is just a type used to create a variable which can be manipulated through method in a program. |
object | Is an instance of a class, which is similar to a variable, defined as an instance of a type. An object is what you actually use in a program since it contains values and can be changed. |
method | Is a function contained within the class. You will find the functions used within a class often referred to as methods in programming literature. |
message | Is similar to function call. In object oriented programming, we send messages instead of calling functions. For the time being, you can think of them as identical. Later you will see that they are in fact slightly different. In programming terms, event or action of the object normally used to describe a consequence of sending message. |
Table 12.1: Some terms definition. |
We have defined that, objects have attributes and by sending message, the object can do something, that is action or something can be done, so there will be an event.
Now for program named class.cpp, we can say that we have a class, composed of one variable and two methods. The methods operate on the variable contained in the class when they receive messages to do so.
Lines 11 and 12 of this program are actually the prototypes for the two methods, and are our first example of a prototype usage within a class as shown below:
void set(int enter_value);
int get_value(void);
You will notice line 11 which says that the method named set() requires one parameter of type int and returns nothing, hence the return type is void. The method named get_value() however, according to line 12 has no input parameters but returns an int type value to the caller.
12.3.4 Sending A Message Or Function Call?
After the definition in lines 2 through 24, we finally come to the program where we actually use the class. In line 29 we instantiate three objects of class item and name the objects John_cat,Joe_cat and Big_cat.
Each object contains a single data point which we can set through the use of the methodset() or read through the use of the get_value() method, but we cannot directly set or read the value of the data point because it is hidden within the block wall around the class as if it is in a container.
In line 32, we send a message to the object named John_cat instructing it to set its internal value to 10, and even though this looks like a function call, it is properly called sending a message to a method. It is shown below:
John_cat.set(10); // assigning values
Remember that the object named John_cat has a method associated with it called set() that sets its internal value to the actual parameter included within the message.
You will notice that the form is very much like the means of accessing the elements of a structure. You mention the name of the object with a dot connecting it to the name of the method.
This means, perform operation set(), with argument 10 on the instance of the object John_cat.
In a similar manner, we send a message to each of the other two objects,Joe_cat and Big_cat, to set their values to those indicated.
Lines 37 and 39 have been commented out because the operations are illegal. The variable named keep_data is private by default and therefore not available to the code outside of the object itself.
Also, the data contained within the object named John_cat is not available within the methods of Joe_cat or Big_cat because they are different objects.
The other method defined for each object is used in lines 43 through 45 to illustrate their usage. In each case, another message is sent to each object and the returned result is output to the standard output, screen, via the stream library cout
There is another variable named garfield declared and used throughout this example program that illustrates, a normal variable can be intermixed with the objects and used in the normal manner.
Compile and run this program. Try removing the comments from lines 37 and 38, and then see what kind of error messages your compiler issues.
Examine the program named robject.cpp carefully, a program with a few serious problems that will be overcome in the next program example by using the principles of encapsulation.
1. // program robject.cpp
2. #include <iostream>
3. using namespace std;
4.
5. // a function prototype
6. int area(int rectangle_height, int rectangle_width);
7.
8. struct rectangle
9. {
10. int height; // public
11. int width; // public
12. };
13.
14. struct pole
15. {
16. int length; // public
17. int depth; // public
18. };
19.
20. // rectangle area
21. int surface_area(int rectangle_height, int rectangle_width)
22. {
23. return (rectangle_height * rectangle_width);
24. }
25.
26. // main program
27. void main ( )
28. {
29. rectangle wall, square;
30. pole lamp_pole;
31.
32. wall.height = 12; // assigning values
33. wall.width = 10;
34. square.height = square.width = 8;
35.
36. lamp_pole.length = 50;
37. lamp_pole.depth = 6;
38.
39. cout<<"Area of wall = height x width, OK!"<< "\n";
40. cout<<"-------------------------------------"<< "\n";
41. cout<<"----> Area of the wall is "<<surface_area(wall.height,
42. wall.width)<< "\n\n";
43. cout<<"Area of square = height x width, OK!"<< "\n";
44. cout<<"-------------------------------------"<< "\n";
45. cout<<"----> Area of square is
46. "<<surface_area(square.height,square.width)<<"\n\n";
47. cout<<"Non related area?"<<"\n = height of square x width of the wall?"<<
48. "\n";
49. cout<<"-------------------------------------"<< "\n";
50. cout<<"----> Non related surface area is
51. "<<surface_area(square.height,wall.width)<<"\n\n";
52. cout<<"Wrong surface area = height of square"<<"\nx depth of lamp
53. pole?"<<"\n";
54. cout<<"-------------------------------------"<< "\n";
55. cout<<"---->Wrong surface area is
56. "<<surface_area(square.height,lamp_pole.depth)<<"\n";
57.
58. // system("pause");
59. }
---------------------------------------------------------------------------------------
We have two structures declared, one being a rectangle and the other is a pole. The depth of the lamp pole is the depth it is buried in the ground, the overall length of the pole is therefore the sum of the height and depth.
Figure 12.3 try to describe the data space after the program execution. It may be a bit confused at the meaning of the result found in line 50 where we multiply the height of the square withwidth of the wall, because the data can be access publicly.
Another one, although it is legal, the result has no meaning because the product of the height of the square and the depth of the lamp_pole has absolutely no meaning in any physical system we can think up in reality because they don’t have relation and the result is useless.
The error is obvious in a program as simple as this, but in a large program production it is very easy for such problems to be inadvertently introduced into the code by a team of programmers and the errors can be very difficult to find.
If we have a program that defined all of the things we can do with a square’s data and another program that defined everything we could do withlamp_pole’s data, and if the data could be kept mutually exclusive, we could prevent these silly things from happening.
If these entities must interact, they cannot be put into separate programs, but they can be put into separate classes to achieve the desired goal. Compile and run the program.
Tenouk C++ encapsulation principles, concepts and implementation