home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Chapter 5
- ENCAPSULATION
-
- As mentioned in Chapter 1, object oriented programming will seem
- very unnatural to a programmer with a lot of procedural
- programming experience. This chapter is the beginning of the
- definition of object oriented programming, and we will study the
- topic of encapsulation which is a "divide and conquer" technique.
- As we stated earlier, there are a lot of new terms used with
- object oriented programming. Don't be intimidated by the new
- terminology, we will study the terms one at a time in a
- meaningful order.
-
- Encapsulation is the process of forming objects which we will
- discuss throughout this chapter. An encapsulated object is often
- called an abstract data type and it is what object oriented
- programming is all about. Without encapsulation, which involves
- the use of one or more classes, there is no object oriented
- programming. Of course there are other topics concerning object
- oriented programming, but this is the cornerstone.
-
-
- WHY BOTHER WITH ENCAPSULATION?
- -----------------------------------------------------------------
- We need encapsulation because we are human, and humans make
- errors. When we properly encapsulate some code, we actually
- build an impenetrable wall to protect the contained code from
- accidental corruption due to the silly little errors that we are
- all prone to make. We also tend to isolate errors to small
- sections of code to make them easier to find and fix. We will
- have a lot more to say about the benefits of encapsulation as we
- progress through the tutorial.
-
-
- NO INFORMATION HIDING
- -----------------------------------------------------------------
- The program named OPEN.CPP is a really stupid ================
- program because it does next to nothing, but OPEN.CPP
- it will be the beginning point for our ================
- discussion of encapsulation, otherwise known
- as information hiding. Information hiding is an important part
- of object oriented programming and you should have a good grasp
- of what it is by the time we finish this chapter.
-
- A very simple structure is defined in lines 4 through 6 which
- contains a single int type variable within the structure. This
- is sort of a silly thing to do, but it will illustrate the
- problem we wish to overcome in this chapter. Three variables are
- declared in line 10, each of which contains a single int type
- variable and each of the three variables are available for use
- anywhere within the main function. Each variable can be
- assigned, incremented, read, modified, or have any number of
-
- Page 5-1
-
- Chapter 5 - Encapsulation
-
- operations performed on it. A few of the operations are
- illustrated in lines 13 through 21 and should be self explanatory
- to anyone with a little experience with the C programming
- language.
-
- An isolated local variable named piggy is declared and used in
- the same section of code to illustrate that there is nothing
- magic about this code. Figure 5-1 is a graphical representation
- of the data space after execution of line 16. Study this simple
- program carefully because it is the basis for beginning our study
- of encapsulation. Be sure to compile and execute this program,
- then we will go on to the next example program where we will see
- our first example of real information hiding.
-
-
- INFORMATION HIDING
- -----------------------------------------------------------------
- Examine the program named CLAS.CPP for our ==================
- first example of a program with a little CLAS.CPP
- information hiding contained in it. This ==================
- program is identical to the last one except
- for the way it does a few of its operations. We will take the
- differences one at a time and explain what is happening. Keep in
- mind that this is a trivial program and the safeguards built into
- it are not needed for such a simple program but are used here to
- illustrate how to use these techniques in a larger much more
- complicated program.
-
- The first difference is that we have a class instead of a
- structure beginning in line 4 of this program. The only
- difference between a class and a structure is that a class begins
- with a private section whereas a structure begins with a private
- section. The keyword class is used to declare a class as
- illustrated here.
-
- The class named one_datum is composed of the single variable
- named data_store and two functions, one named set() and the other
- named get_value(). A more complete definition of a class is a
- group of variables, and one or more functions that can operate on
- that data. Stay with us, we will tie this all together in a
- meaningful and useful way very soon.
-
-
- WHAT IS A PRIVATE SECTION?
- -----------------------------------------------------------------
- All data at the beginning of a class defaults to private.
- Therefore, the data at the beginning of the class cannot be
- accessed outside of the class, it is hidden from any outside
- access. Therefore, the variable named data_store which is a part
- of the object (an object will be defined completely later) named
- dog1 declared in line 23, is not available for use anywhere in
- the main program. It is as if we have built a "brick wall"
- around the variables to protect them from accidental corruption
-
- Page 5-2
-
- Chapter 5 - Encapsulation
-
- by outside programming influences. It seems a little dumb to
- declare a variable in the main program that we cannot use, but
- that is exactly what we did.
-
- Figure 5-2 is a graphical representation of the class with its
- "brick wall" built around the data to protect it. You will
- notice the small peep holes we have opened up to allow the user
- to gain access to the functions. The peep holes were opened by
- declaring the functions in the public section of the class.
-
-
- WHAT IS A PUBLIC SECTION?
- -----------------------------------------------------------------
- A new keyword, public, is introduced in line 6 which states that
- anything following this keyword can be accessed from outside of
- this class. Because the two functions are defined following the
- keyword public, they are both public and available for use by
- any calling program that is within the scope of this object.
- This essentially opens two small peepholes in the solid wall of
- protection that we built around the class. You should keep in
- mind that the private variable is not available to the calling
- program. Thus, we can only use the variable by calling one of
- the two functions defined within the public part of the class.
- These are called member functions because they are members of the
- class.
-
- Since we have declared two functions, we need to define them by
- saying what each function will actually do. This is done in
- lines 11 through 19 where they are each defined in the normal
- way, except that the class name is prepended onto the function
- name and separated from it by a double colon. 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 must know with which class to
- associate each function implementation.
-
- One of the key points to be made here is 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, but 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 the function names of
- this class when defining them. Figure 5-3 depicts the data space
- following execution of line 29.
-
- It would be well to mention at this point that it is legal to
- include variables and functions in the private part, and
- additional variables and functions in the public part also. In
- most practical situations, variables are included in only the
- private part and functions are included in only the public part
- of a class definition. Occasionally, variables or functions are
-
- Page 5-3
-
- Chapter 5 - Encapsulation
-
- used 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.
-
- In C++ we have three scopes of variables, local, file and class.
- Local variables are localized to a single function. File
- variables, those that are defined outside of any function, are
- available anywhere in a file following their definition. A
- variable with class scope is available anywhere within the scope
- of a class and nowhere else. The variable named data_store has a
- class scope.
-
- You must be very confused by this point since we have given a lot
- of rules but few reasons for doing all of this. Stay with us and
- you will soon see that there are very practical reasons for doing
- all of this.
-
-
- MORE NEW TERMINOLOGY
- -----------------------------------------------------------------
- As with most new technologies, developers seem to delight in
- making up new names for all aspects of their new pet. Object
- oriented programming is no different, so we must learn new names
- for some of our old familiar friends if we are going to learn how
- to effectively use it. To help you learn this new programming
- terminology, we will list a few of them here and begin using them
- in the text to get you used to seeing and using them. You will
- not understand them all yet, but we need to introduce them early.
-
- A class is a grouping of data and methods (functions). A
- class is very much like a structure type as used in ANSI-C,
- it is only a pattern to be used to create a variable which
- can be manipulated in a program.
-
- An 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 has values and
- can be changed.
-
- A 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.
-
- A message is the same thing as a 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 in this tutorial we will see that they
- are in fact slightly different.
-
- With all the new terminology, we will continue our study of the
- program named CLAS.CPP and show you how to use the class. We can
- now say that we have a class composed of one variable and two
- methods. The methods operate on the variable contained in the
-
- Page 5-4
-
- Chapter 5 - Encapsulation
-
- class when they receive messages to do so. In this tutorial we
- will use the terms object and variable interchangeably because
- both names are very descriptive of what the object really is.
-
- This is a small point but it could be easily overlooked. Lines 7
- and 8 of this program are actually the prototypes for the two
- methods, and is our first example of the use of a prototype
- within a class. This is the reason we spent so much time
- studying prototypes in the last chapter. You will notice line 7
- 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 8, has no
- input parameters but returns an int type value to the caller.
-
-
- SENDING A MESSAGE
- -----------------------------------------------------------------
- Following all of the definitions in lines 1 through 19, we
- finally come to the program where we actually use the class. In
- line 23 we declare three objects of the class one_datum and name
- the objects dog1, dog2, and dog3. Each object contains a single
- data point which we can set through use of one method or read its
- value through use of the other 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. In line 26, we send a message
- to the object named dog1 instructing it to set its internal value
- to 12, and even though this looks like a function call, it is
- properly called sending a message to a method. Remember that the
- object named dog1 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. In a similar manner, we send a message to
- each of the other two objects dog2 and dog3 to set their values
- to those indicated.
-
- Lines 31 and 32 have been commented out because the operations
- are illegal. The variable named data_store is private and
- therefore not available to the code outside of the object
- itself. It should be obvious, but it will be pointed out that
- the data contained within the object named dog1 is not available
- within the methods of dog2 or dog3 because they are different
- objects. These rules are all devised to help you develop better
- code more quickly and you will soon see how they help.
-
- The other method defined for each object is used in lines 34
- through 36 to illustrate how it can be used. In each case,
- another message is sent to each object and the returned result is
- output to the monitor via the stream library.
-
-
-
-
- Page 5-5
-
- Chapter 5 - Encapsulation
-
- USING A NORMAL VARIABLE
- -----------------------------------------------------------------
- There is another variable named piggy declared and used
- throughout this example program that illustrates that a normal
- variable can be intermixed with the objects and used in the
- normal manner. The use of this variable should pose no problem
- to you, so after you understand the program, be sure to compile
- and execute it. It would be a good exercise for you to remove
- the comments from lines 31 and 32 to see what kind of error
- message your compiler issues.
-
- This program illustrates information hiding but it will not be
- clear to you that it really does anything worthwhile until we
- study the next two programs. Be sure to compile and execute this
- program, then remove the comments from lines 31 and 32 as
- suggested to see the error messages issued.
-
-
- A PROGRAM WITH PROBLEMS
- -----------------------------------------------------------------
- Examine the program named OPENPOLE.CPP for an ==================
- example of a program with a few serious OPENPOLE.CPP
- problems that will be overcome in the next ==================
- example program by using the principles of
- encapsulation.
-
- We have two structures declared, one being a rectangle and the
- other a pole. The data fields should be self explanatory with
- the exception of the depth of the flagpole which is the depth it
- is buried in the ground, the overall length of the pole is
- therefore the sum of the length and the depth.
-
- Figure 5-4 depicts the data space for this program after
- execution of line 32. Based on your experience with ANSI-C, you
- should have no problem understanding exactly what this program
- is doing, but you may be a bit confused at the meaning of the
- result found in line 38 where we multiply the height of the
- square with the width of the box. This is perfectly legal to do
- in ANSI-C or C++, but the result has no earthly meaning because
- the data are for two different entities. Likewise, the result
- calculated in line 40 is even sillier because the product of the
- height of the square and the depth of the flagpole has absolutely
- no meaning in any physical system we can think up.
-
- Wouldn't it be neat if we had a way to prevent such stupid things
- from happening in a large production program. If we had a good
- program that defined all of the things we can do with a square
- and another program that defined everything we could do with a
- pole, and if the data could be kept mutually exclusive, we could
- prevent these silly things from happening.
-
- It should come as no real surprise to you that the next program
- will do just those things for us and do it in a very elegant way.
-
- Page 5-6
-
- Chapter 5 - Encapsulation
-
- Before proceeding on to the next example program, you should
- compile and execute this one even though it displays some silly
- results.
-
-
- OBJECTS PROTECT DATA
- -----------------------------------------------------------------
- Examine the program named CLASPOLE.CPP as an ==================
- example of data protection in a very simple CLASPOLE.CPP
- program. In this program the rectangle is ==================
- changed to a class with the same two
- variables which are now private, and two methods to handle the
- private data. One method is used to initialize the values of the
- objects created and the other method returns the area of the
- object. The two methods are defined in lines 12 through 21 in
- the manner described earlier in this chapter. The pole is left
- as a structure to illustrate that the two can be used together
- and that C++ is truly an extension of ANSI-C.
-
- In line 33 we declare two objects, once again named box and
- square, but this time we cannot assign values directly to their
- individual components because they are private elements of the
- class. Figure 5-5 is a graphical illustration of the two objects
- available for use within the calling program. Lines 36 through
- 38 are commented out for that reason and the messages are sent to
- the objects in lines 40 and 41 to tell them to initialize
- themselves to the values input as parameters. The flag_pole is
- initialized in the same manner as in the previous program. Using
- the class in this way prevents us from making the silly
- calculations we did in the last program, because we can only
- calculate the area by using the data stored in one object. The
- compiler is now being used to prevent the erroneous calculations.
- The end result is that the stupid calculations we did in the last
- program are not possible in this program, so lines 50 through 53
- have been commented out. Once again, it is difficult to see the
- utility of this in such a simple program. In a large program,
- using the compiler to enforce the rules can pay off in a big way.
-
- Even though the square and the box are both objects of class
- rectangle, their private data is hidden from each other such that
- neither can purposefully or accidentally change the other's data.
-
- This is the abstract data type mentioned earlier in this chapter,
- a model with a set of private variables for data storage and a
- set of operations that can be performed on that stored data. The
- only operations that can be performed on the data are those
- defined by the methods, which prevents many kinds of erroneous or
- silly operations. Encapsulation and data hiding bind the data
- and procedures, or methods, tightly together and limit the scope
- and visibility of each. Once again, we have the divide and
- conquer technique in which an object is separated from the rest
- of the code and carefully developed in complete isolation from
-
-
- Page 5-7
-
- Chapter 5 - Encapsulation
-
- it. Only then is it integrated into the rest of the code with a
- few very simple interfaces.
-
-
- HAVE YOU EVER USED THIS TECHNIQUE BEFORE?
- -----------------------------------------------------------------
- A good example of the use of this technique is in the file
- commands you have been using with ANSI-C. The data in the file
- is only available through the predefined functions provided by
- your compiler writer. You have no direct access to the actual
- data because it is impossible for you to address the actual data
- stored on the disk. The data is therefore private data, as far
- as you are concerned, but the available functions are very much
- like methods in C++. There are two aspects of this technique
- that really count when you are developing software. First, you
- can get all of the data you really need from the file system
- because the interface is complete, but secondly, you cannot get
- any data that you do not need. You are prevented from getting
- into the file handling system and accidentally corrupting some
- data stored within it. You are also prevented from using the
- wrong data because the functions available demand a serial access
- to the data.
-
- Another example is in the monitor and keyboard handling routines.
- You are prevented from getting into the workings of them and
- corrupting them accidentally, or on purpose if you have such a
- bent, but once again, you are provided with all of the data
- interfaces that you really need.
-
- Suppose you are developing a program to analyze some
- characteristics of flagpoles. You would not wish to
- accidentally use some data referring to where the flagpole
- program was stored on your hard disk as the height of the
- flagpole, nor would you wish to use the cursor position as the
- flagpole thickness or color. All code for the flagpole is
- developed alone, and only when it is finished, is it available
- for external use. When using it, you have a very limited number
- of operations which you can do with the class. The fact that
- the data is hidden from you protects you from accidentally doing
- such a thing when you are working at midnight to try to meet a
- schedule. Once again, this is referred to as information hiding
- and is one of the primary advantages of object oriented
- programming over procedural techniques.
-
- Based on the discussion given above you can see that object
- oriented programming is not really new, since it has been used in
- a small measure for as long as computers have been popular. The
- newest development, however, is in allowing the programmer to
- partition his programs in such a way that he too can practice
- information hiding and reduce the debugging time.
-
-
-
-
- Page 5-8
-
- Chapter 5 - Encapsulation
-
- WHAT DOES THIS COST?
- -----------------------------------------------------------------
- It should be clear that this technique will cost you something in
- efficiency because every access to the elements of the object
- will require the time and inefficiency of a call to a function,
- or perhaps I should be more proper and refer to it as a method.
- The time saved in building a large program, however, could easily
- be saved in debug time when it comes time to iron out the last
- few bugs. This is because a program made up of objects that
- closely match the application are much easier to understand than
- a program that does not.
-
- This is obviously such a small program that it is silly to try to
- see any gain with this technique. In a real project however, it
- could be a great savings if one person developed all of the
- details of the rectangle, programmed it, and made it available to
- you to simply use. This is exactly what has been done for you if
- you consider the video monitor an object. There is a complete
- set of preprogrammed and debugged routines you can use to make
- the monitor do anything you wish it to do, all you have to do is
- study the interface to the routines and use them, expecting them
- to work. As we mentioned earlier, it is impossible for you to
- multiply the size of your monitor screen by the depth of the flag
- pole because that information is not available to you to use in a
- corruptible way.
-
- After you understand some of the advantages of this style of
- programming, be sure to compile and execute this program.
-
-
- CONSTRUCTORS AND DESTRUCTORS
- -----------------------------------------------------------------
- The file named CONSPOLE.CPP introduces ==================
- constructors and destructors and should be CONSPOLE.CPP
- examined at this time. This example program ==================
- is identical to the last example except that
- a constructor has been added as well as a destructor. The
- constructor always has the same name as the class itself and is
- declared in line 8, then defined in lines 14 through 18. The
- constructor is called automatically by the C++ system when the
- object is declared and prevents the use of an uninitialized
- variable. When the object named box is declared in line 46, the
- constructor is called automatically by the system. The
- constructor sets the values of height and width each to 6 in the
- object named box. This is printed out for reference in lines 49
- and 50. Likewise, when the square is declared in line 46, the
- values of the height and the width of the square are each
- initialized to 6 when the constructor is called automatically.
-
- A constructor is defined as having the same name as the class
- itself. In this case both are named rectangle. The constructor
- cannot have a return type associated with it because of the
- definition of C++. It actually has a predefined return type, a
-
- Page 5-9
-
- Chapter 5 - Encapsulation
-
- pointer to the object itself, but we will not be concerned about
- this until much later in this tutorial. Even though both objects
- are assigned values by the constructor, they are initialized in
- lines 58 and 59 to new values and processing continues. Since we
- have a constructor that does the initialization, we should
- probably rename the method named initialize() something else but
- it illustrates the concept involved here.
-
- The destructor is very similar to the constructor except that it
- is called automatically when each of the objects goes out of
- scope. You will recall that automatic variables have a limited
- lifetime because they cease to exist when the enclosing block in
- which they were declared is exited. When an object is about to
- be automatically deallocated, its destructor, if one exists, is
- called automatically. A destructor is characterized as having
- the same name as the class but with a tilde prepended to the
- class name. A destructor has no return type.
-
- A destructor is declared in line 11 and defined in lines 31
- through 35. In this case the destructor only assigns zeros to
- the variables prior to their being deallocated, so nothing is
- really accomplished. The destructor is only included for
- illustration of how it is used. If some blocks of memory were
- dynamically allocated within an object, a destructor should be
- used to deallocate them prior to losing the pointers to them.
- This would return their memory to the free store for further use
- later in the program.
-
- It is interesting to note that if a constructor is used for an
- object that is declared prior to the main program, a global
- variable, the constructor will actually be executed prior to the
- execution of the main program. In like manner, if a destructor
- is defined for such a variable, it will execute following the
- completion of execution of the main program. This will not
- adversely affect your programs, but it is interesting to make
- note of.
-
-
- OBJECT PACKAGING
- -----------------------------------------------------------------
- Examine the file named BOXES1.CPP for an ==================
- example of how not to package an object for BOXES1.CPP
- universal use. This packaging is actually ==================
- fine for a very small program, but is meant
- to illustrate to you how to split your program up into smaller,
- more manageable files when you are developing a large program or
- when you are part of a team developing a large system. The next
- three example programs in this chapter will illustrate the proper
- method of packaging a class.
-
- This program is very similar to the last one with the pole
- structure dropped and the class named box. The class is defined
- in lines 4 through 12, the implementation of the class is given
-
- Page 5-10
-
- Chapter 5 - Encapsulation
-
- in lines 15 through 34, and the use of the class is given in
- lines 37 through 50. With the explanation we gave about the last
- example program, the diligent student should have no problem
- understanding this program in detail.
-
-
- INLINE IMPLEMENTATION
- -----------------------------------------------------------------
- The method in line 10 contains the implementation for the method
- as a part of the declaration because it is very simple, and
- because it introduces another new topic which you will use often
- in C++ programming. When the implementation is included in the
- declaration, it will be assembled inline wherever this function
- is called leading to much faster code. This is because there is
- no overhead to accomplish the call to the method. In some cases
- this will lead to code that is both smaller and faster. This is
- yet another illustration of the efficiency built into the C++
- programming language.
-
- Compile and execute this program in preparation for our study of
- the next three examples which are a repeat of this program in a
- slightly different form.
-
-
- THE CLASS HEADER FILE
- -----------------------------------------------------------------
- If you examine BOX.H carefully, you will see ===============
- that it is only the class definition. No BOX.H
- details are given of how the various methods ===============
- are implemented except of course for the
- inline method named get_area(). This gives the complete
- definition of how to use the class with no implementation details.
- You would be advised to keep a hardcopy of this file available as
- we study the next two files. You will notice that it contains
- lines 4 through 12 of the previous example program named
- BOXES1.CPP. This is called the class header file and cannot be
- compiled or executed.
-
-
- THE CLASS IMPLEMENTATION FILE
- -----------------------------------------------------------------
- Examine the file named BOX.CPP for the =================
- implementation of the methods declared in BOX.CPP
- the class header file. Notice that the class =================
- header file is included into this file in
- line 2 which contains the prototypes for its methods and the
- definitions of the variables to be manipulated. The code from
- lines 15 through 34 of BOXES1.CPP is contained in this file which
- is the implementation of the methods declared in the class named
- box.
-
- This file can be compiled but it cannot be executed because there
- is no main entry point which is required for all ANSI-C or C++
-
- Page 5-11
-
- Chapter 5 - Encapsulation
-
- programs. When it is compiled, the object code will be stored in
- the current directory and available for use by other programs.
- It should be noted here that the result of compilation is usually
- referred to as an object file because it contains object code.
- This use of the word object has nothing to do with the word
- object as used in object oriented programming. It is simply a
- matter of overloading the use of the word. The practice of
- referring to the compiled result as an object file began long
- before the technique of object oriented programming was ever
- considered.
-
- The separation of the definition and the implementation is a
- major step forward in software engineering. The definition file
- is all the user needs in order to use this class effectively in a
- program. He needs no knowledge of the actual implementation of
- the methods. If he had the implementation available, he may
- study the code and find a trick he could use to make the overall
- program slightly more efficient, but this would lead to
- nonportable software and possible bugs later if the implementor
- changed the implementation without changing the interface. The
- purpose of object oriented programming is to hide the
- implementation in such a way that the implementation can not
- affect anything outside of its own small and well defined
- boundary or interface.
-
- You should compile this implementation file now and we will use
- the result with the next example program.
-
-
- USING THE BOX OBJECT
- -----------------------------------------------------------------
- Examine the file named BOXES2.CPP and you ==================
- will find that the class we defined BOXES2.CPP
- previously is used within this file. In ==================
- fact, these last three programs taken
- together are identical to the program named BOXES1.CPP studied
- earlier. The BOX.H file is included here, in line 3, since the
- definition of the box class is needed to declare three objects
- and use their methods. You should have no trouble seeing that
- this is a repeat of the previous program and will execute in
- exactly the same way. There is a big difference in BOXES1.CPP
- and BOXES2.CPP as we will see shortly.
-
- A very important distinction must be made at this point. We are
- not merely calling functions and changing the terminology a
- little to say we are sending messages. There is an inherent
- difference in the two operations. Since the data for each object
- is tightly bound up in the object, there is no way to get to the
- data except through the methods and we send a message to the
- object telling it to perform some operation based on its
- internally stored data. However, whenever we call a function, we
- take along the data for it to work with as parameters since it
- doesn't contain its own data.
-
- Page 5-12
-
- Chapter 5 - Encapsulation
-
-
- Be sure to compile and execute this program, but when you come to
- the link step, you will be required to link this program along
- with the result of the compilation when you compiled the class
- named box. The file is probably named BOX.OBJ that must be
- linked with this file. You may need to consult the documentation
- for your C++ compiler to learn how to do this. Even if it seems
- to be a lot of trouble to learn how to link several files
- together, it will be worth your time to do so now because we will
- be linking several more multifile C++ programs in the remainder
- of this tutorial.
-
- Depending on your compiler, this is your first opportunity to use
- either a project file, or the "make" facility included with your
- compiler. Regardless of which C++ compiler you are using, it
- would pay you to stop and learn how to use the multifile
- technique provided with your compiler because you will need to
- use it several times before the end of this tutorial. The nature
- of C++ tends to drive the programmer to use many files for a
- given programming project and you should develop the habit early.
-
-
- INFORMATION HIDING
- -----------------------------------------------------------------
- The last three example programs illustrate a method of
- information hiding that can have a significant impact on the
- quality of software developed for a large project. Since the
- only information the user of the class really needs is the class
- header, that is all he needs to be given. The details of
- implementation can be kept hidden from him to prevent him from
- studying the details and possibly using a quirk of programming to
- write some rather obtuse code. Since he doesn't know exactly
- what the implementor did, he must follow only the definition
- given in the header file. This can have a significant impact on
- a large project. As mentioned earlier, accidental corruption of
- data is prevented also.
-
- Another reason for hiding the implementation is economic. The
- company that supplied you with your C++ compiler gave you many
- library functions but did not supply the source code to the
- library functions, only the interface to each function. You know
- how to use the file access functions but you do not have the
- details of implementation, nor do you need them. Likewise a
- class library industry can develop which supplies users with
- libraries of high quality, completely developed and tested
- classes, for a licensing fee of course. Since the user only
- needs the interface defined, he can be supplied with the
- interface and the object (compiled) code for the class and can
- use it in any way he desires. The suppliers source code is
- protected from accidental or intentional compromise and he can
- maintain complete control over it.
-
-
-
- Page 5-13
-
- Chapter 5 - Encapsulation
-
- It is very important that you understand the principles covered
- in this chapter before proceeding on to the next chapter. If you
- feel you are a little weak in any of the areas covered here, you
- should go over them again before proceeding on. A point that
- should be made here that may be obvious to you, is that it
- requires a considerable amount of forethought to effectively use
- classes.
-
-
- ABSTRACT DATA TYPES
- -----------------------------------------------------------------
- We mentioned the abstract data type at the beginning of this
- chapter and again briefly midway through, and it is time to
- describe it a little more completely. An abstract data type is a
- group of data, each of which can store a range of values, and a
- set of methods or functions that can operate on that data. Since
- the data are protected from any outside influence, it is
- protected and said to be encapsulated. Also, since the data is
- somehow related, it is a very coherent group of data that may be
- highly interactive with each other, but with little interaction
- outside the scope of its class.
-
- The methods, on the other hand, are coupled to the outside world
- through the interface, but there are a limited number of contacts
- with the outside world and therefore a weak coupling with the
- outside. The object is therefore said to be loosely coupled to
- the outside world. Because of the tight coherency and the loose
- coupling, ease of maintenance of the software is greatly
- enhanced. The ease of maintenance may be the greatest benefit of
- object oriented programming.
-
- It may bother you that even though the programmer may not use the
- private variables directly outside of the class, they are in
- plain sight and he can see what they are and can probably make a
- good guess at exactly how the class is implemented. The
- variables could have been hidden completely out of sight in
- another file, but because the designers of C++ wished to make the
- execution of the completed application as efficient as possible,
- the variables were left in the class definition where they can be
- seen but not used.
-
-
- FRIEND FUNCTIONS
- -----------------------------------------------------------------
- A function outside of a class can be defined to be a friend
- function by the class which gives the friend free access to the
- private members of the class. This in effect, opens a small hole
- in the protective shield of the class, so it should be used very
- carefully and sparingly. There are cases where it helps to make
- a program much more understandable and allows controlled access
- to the data. Friend functions will be illustrated in some of the
- example programs later in this tutorial. It is mentioned here
- for completeness of this section. A single isolated function can
-
- Page 5-14
-
- Chapter 5 - Encapsulation
-
- be declared as a friend, as well as members of other classes, and
- even entire classes can be given friend status if needed in a
- program. Neither a constructor nor a destructor can be a friend
- function.
-
-
- THE struct IN C++
- -----------------------------------------------------------------
- The struct is still useable in C++ and operates just like it does
- in ANSI-C with one addition. You can include methods in a
- structure that operate on data in the same manner as in a class,
- but methods and data are automatically defaulted to be public at
- the beginning of a structure. Of course you can make any of the
- data or methods private by defining a private section within the
- structure. The structure should be used only for constructs that
- are truly structures. If you are building even the simplest
- objects, you are advised to use classes to define them.
-
-
- A VERY PRACTICAL CLASS
- -----------------------------------------------------------------
- The examples of encapsulation used in this chapter have all been
- extremely simple in order to illustrate the mechanics of
- encapsulation. Since it would be expedient to study a larger
- example, the date class is given for your instruction. The date
- class is a complete nontrivial class which can be used in any
- program to get the current date and print it as an ASCII string
- in any of four predefined formats. It can also be used to store
- any desired date and format it for display.
-
- Examine the file named DATE.H which is the ================
- header file for the date class. This file is DATE.H
- so well commented that we don't have much ================
- else to say about it. If you understand the
- principles covered in this chapter you should have no problem
- understanding this class. One thing that is new to you is the
- reserved word protected which is used in line 12. We will define
- this word in a couple of chapters. Until then, pretend that it
- means the same thing as private and you will be close enough for
- this present example. The code in lines 8 and 9 along with line
- 55 will be explained shortly. For the present time, simply
- pretend those lines of code are not there. Also the keyword
- static as used in lines 16 and 17 will be explained later. These
- new constructs are added because we plan to use this class later
- when we study inheritance.
-
- You should spend the time necessary to completely understand this
- class header, with the exception of the new things added, before
- going on to the implementation for this class.
-
- The file named DATE.CPP is the implementation ================
- for the date class and once again, there is DATE.CPP
- nothing unusual or difficult about this code. ================
-
- Page 5-15
-
- Chapter 5 - Encapsulation
-
- It uses very simple logic to store and format
- the date in a usable manner. You should study this code until
- you understand it completely before going on to the next example
- which will use the date class in a main program.
-
- The very simple program named USEDATE.CPP is =================
- a main program that uses the date class to USEDATE.CPP
- list the current date and another date on the =================
- monitor. Once again, you should have no
- problem understanding this program so nothing more will be said
- about it.
-
- You should spend the time necessary to understand these three
- files because they are the starting point for a practical track
- in the next few chapters. This class will be used in conjunction
- with others to illustrate single and multiple inheritance. Even
- though you do not understand all of the details of these files,
- spend enough time that you are comfortable with the structure and
- the major points of them.
-
- We will continue our discussion of encapsulation in the next chapter.
-
-
- PROGRAMMING EXERCISES
- -----------------------------------------------------------------
- 1. Add a method to CLAS.CPP which will supply the square of the
- stored value. Include some code in the main program to read
- and display the squared values.
-
- 2. Continuing with CLAS.CPP, add a constructor to initialize the
- stored value to 10 and add a few lines of code to the main
- program to display the values immediately following the
- object definition.
-
- 3. Add an output statement to the rectangle constructor of the
- program named CONSPOLE.CPP and another to the destructor to
- prove to yourself that they really are called by the system
- when we said they are.
-
- 4. Write a more comprehensive program to use the date class
- presented at the end of this chapter.
-
- 5. Write a name class which is somewhat similar to the date
- class which can store any name in three parts and return the
- full name in any of several different formats such as the
- following;
-
- John Paul Doe
- J. P. Doe
- Doe, John Paul
- and any other formats you desire.
-
- If this is carefully planned, it could be useful to you
- someday.
- Page 5-16
-