home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
-
-
- Chapter 9
- MULTIPLE INHERITANCE AND FUTURE DIRECTIONS
-
- C++ version 2.0 was released by AT&T during the summer of 1989, and
- the major addition to the language is multiple inheritance, the
- ability to inherit data and methods from more than one class into
- a subclass. Multiple inheritance and a few of the other additions
- to the language will be discussed in this chapter along with some
- of the expected future directions of the language.
-
- Several companies have C++ compilers available in the marketplace,
- and many others are sure to follow. Because the example programs
- in this tutorial are designed to be as generic as possible, most
- should be compilable with any good quality C++ compiler provided
- it follows the AT&T definition of version 2.1 or newer. Many of
- these examples will not work with earlier definitions because the
- language was significantly changed with the version 2.1 update.
-
- After completing this tutorial, you should have enough experience
- with the language to study additional new constructs on your own
- as they are implemented by the various compiler writers. We will
- update the entire tutorial as soon as practical following
- procurement of any new compiler, but hopefully the language will
- not change rapidly enough now to warrant an update oftener than
- annually. Please feel free to contact us for information on
- updates to the Coronado Enterprises C++ tutorial.
-
-
- MULTIPLE INHERITANCE
- _________________________________________________________________
-
- A major recent addition to the C++ language is the ability to
- inherit methods and variables from two or more parent classes when
- building a new class. This is called multiple inheritance, and is
- purported by many people to be a major requirement for an object
- oriented programming language. Some writers, however, have
- expressed doubts as to the utility of multiple inheritance. To
- illustrate the validity of this, it was not easy to think up a good
- example of the use of multiple inheritance as an illustration for
- this chapter. In fact, the resulting example is sort of a forced
- example that really does nothing useful. It does however,
- illustrate the mechanics of the use of multiple inheritance with
- C++, and that is our primary concern at this time.
-
- The biggest problem with multiple inheritance involves the
- inheritance of variables or methods from two or more parent classes
- with the same name. Which variable or method should be chosen as
- the inherited variable or method if two or more have the same name?
- This will be illustrated in the next few example programs.
-
-
- Page 9-1
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
-
- SIMPLE MULTIPLE INHERITANCE
- _________________________________________________________________
-
- An examination of the file named MULTINH1.CPP ================
- will reveal the definition of two very simple MULTINH1.CPP
- classes in lines 4 through 27 named moving_van ================
- and driver.
-
- In order to keep the program as simple as possible, all of the
- member methods are defined as inline functions. This puts the code
- for the methods where it is easy to find and study. You will also
- notice that all variables in both classes are declared to be
- protected so they will be readily available for use in any class
- which inherits them. The code for each class is kept very simple
- so that we can concentrate on studying the interface to the methods
- rather than spending time trying to understand complex methods.
- As mentioned previously, chapter 12 will illustrate the use of non-
- trivial methods.
-
- In line 30, we define another class named driven_truck which
- inherits all of the data and all of the methods from both of the
- previously defined classes. In the last two chapters, we studied
- how to inherit a single class into another class, and to inherit
- two or more classes, the same technique is used except that we use
- a list of inherited classes separated by commas as illustrated in
- line 30. The observant student will notice that we use the keyword
- public prior to the name of each inherited class in order to be
- able to freely use the methods within the subclass. In this case,
- we didn't define any new variables, but we did introduce two new
- methods into the subclass in lines 32 through 39.
-
- We declared an object named chuck_ford which presumably refers to
- someone named Chuck who is driving a Ford moving van. The object
- named chuck_ford is composed of four variables, three from the
- moving_van class, and one from the driver class. Any of these four
- variables can be manipulated in any of the methods defined within
- the driven_truck class in the same way as in a singly inherited
- situation. A few examples are given in lines 47 through 56 of the
- main program and the diligent student should be able to add
- additional output messages to this program if he understands the
- principles involved.
-
- All of the rules for private or protected variables and public or
- private method inheritance as used with single inheritance extends
- to multiple inheritance.
-
-
- DUPLICATED METHOD NAMES
- _________________________________________________________________
-
- You will notice that both of the parent classes have a method named
- initialize(), and both of these are inherited into the subclass
- with no difficulty. However, if we attempt to send a message to
-
- Page 9-2
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
- one of these methods, we will have a problem, because the system
- does not know which we are referring to. This problem will be
- solved and illustrated in the next example program.
-
- Before going on to the next example program, it should be noted
- that we have not declared any objects of the two parent classes in
- the main program. Since the two parent classes are simply normal
- classes themselves, it should be apparent that there is nothing
- magic about them and they can be used to define and manipulate
- objects in the usual fashion. You may wish to do this to review
- your knowledge of simple classes and objects of those classes.
-
- Be sure to compile and execute this program after you understand
- its operation completely.
-
-
-
- MORE DUPLICATE METHOD NAMES
- _________________________________________________________________
-
- The second example program in this chapter named ================
- MULTINH2.CPP, illustrates the use of classes MULTINH2.CPP
- with duplicate method names being inherited into ================
- a derived class.
-
- If you study the code, you will find that a new method has been
- added to all three of the classes named cost_per_full_day(). This
- was done intentionally to illustrate how the same method name can
- be used in all three classes. The class definitions are no problem
- at all, the methods are simply named and defined as shown. The
- problem comes when we wish to use one of the methods since they are
- all the same name and they have the same numbers and types of
- parameters and identical return types. This prevents some sort of
- an overloading rule to disambiguate the message sent to one or more
- of the methods.
-
- The method used to disambiguate the method calls are illustrated
- in lines 60, 64, and 68 of the main program. The solution is to
- prepend the class name to the method name with the double colon as
- used in the method implementation definition. This is referred to
- as qualifying the method name. Qualification is not necessary in
- line 68 since it is the method in the derived class and it will
- take precedence over the other method names. Actually, you could
- qualify all method calls, but if the names are unique, the compiler
- can do it for you and make your code easier to write and read.
-
- Be sure to compile and execute this program and study the results.
- The observant student will notice that there is a slight
- discrepancy in the results given in lines 79 through 81, since the
- first two values do not add up to the third value exactly. This
- is due to the limited precision of the float variable but should
- cause no real problem.
-
-
-
- Page 9-3
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
-
- DUPLICATED VARIABLE NAMES
- _________________________________________________________________
-
- If you will examine the example program named ================
- MULTINH3.CPP, you will notice that each base MULTINH3.CPP
- class has a variable with the same name. ================
-
- According to the rules of inheritance, an object
- of the driven_truck class will have two variables with the same
- name, weight. This would be a problem if it weren't for the fact
- that C++ has defined a method of accessing each one in a well
- defined way. You have probably guessed that we will use
- qualification to access each variable. Lines 38 and 45 illustrate
- the use of the variables. It may be obvious, but it should be
- explicitly stated, that there is no reason that the subclass itself
- cannot have a variable of the same name as those inherited from the
- parent classes. In order to access it, no qualification would be
- required.
-
- It should be apparent to you that once you understand single
- inheritance, multiple inheritance is nothing more than an extension
- of the same rules. Of course, if you inherit two methods or
- variables of the same name, you must use qualification to allow the
- compiler to select the correct one.
-
-
- PRACTICAL MULTIPLE INHERITANCE
- _________________________________________________________________
-
- Examine the example program named DATETIME.H ================
- for a practical example using multiple DATETIME.H
- inheritance. You will notice that we are ================
- returning to our familiar date and time classes
- from earlier chapters.
-
- There is a good deal to be learned from this very short header file
- since it is our first example of member initialization. There are
- two constructors for this class, the first being a very simple
- constructor that does nothing in itself as is evident from an
- examination of line 12. This constuctor allows the constructors
- to be executed for the classes new_date and time_of_day. In both
- cases a constructor will be executed that requires no parameters,
- and such a constructor is available for each of these two classes.
-
- The second constuctor is more interesting since it does not simply
- use the default constructor, but instead passes some of the input
- parameters to the inherited class constructors. Following the
- colon in line 13 are two member initializers which are used to
- initialize members of this class. Since the two parent classes are
- inherited, they are also members of this class and can be
- initialized as shown. Each of the member initializers is actually
- a call to a constructor of the parent classes and it should be
- evident that there must be a constructor with the proper number of
-
- Page 9-4
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
- input parameters to respond to the messages given. You will note
- that in line 14, we are actually calling the constructor with no
- parameters given explicitly. If we chose, we could simply let the
- system call that constructor automatically, but this gives us an
- explicit comment on what is happening.
-
-
- MORE ABOUT MEMBER INITIALIZERS
- _________________________________________________________________
-
- Actually, we can use the member initializer to initialize class
- members also. If we had a class member of type int named
- member_var, we could initialize it also by mentioning the name of
- the member followed by the value we desired to initialize it to in
- parentheses. If we wished to initialize it to the value 13, we
- could use the following line of code in the member initializer
- list;
-
- member_var(13);
-
- Following all member initialization, the normal constructor code
- is executed which in this case is given in line 16.
-
-
- ORDER OF MEMBER INITIALIZATION
- _________________________________________________________________
-
- The order of member initialization may seem a bit strange, but it
- does follow a few simple rules. The order of member initialization
- does not follow the order given by the initialization list, but
- another very strict order over which you have complete control.
- All inherited classes are initialized first in the order they are
- listed in the class header. If lines 14 and 15 were reversed,
- class new_date would still be initialized first because it is
- mentioned first in line 8. It has been mentioned that C++ respects
- its elders and initializes its parents prior to itself. That
- should be a useful memory aid in the use of member initializers.
-
- Next, all local class members are initialized in the order in which
- they are declared in the class, not the order in which they are
- declared in the initialization list. Actually, it would probably
- be good practice to not use the member initializer to initialize
- class members but instead to initialize them in the normal
- constructor code.
-
- Finally, after the member initializers are all executed in the
- proper order, the main body of the constructor is executed in the
- normal manner.
-
- USING THE NEW CLASS
- _________________________________________________________________
-
- The example program named USEDTTM.CPP uses the datetime class we
- just built, and like our previous examples, the main program is
-
- Page 9-5
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
- kept very simple and straight forward. You will ===============
- note that the default constructor is used for USEDTTM.CPP
- the object named now, and the constructor with ===============
- the member initializers is used with the objects
- named birthday and special.
-
- The diligent student should have no trouble understanding the
- remaining code in this example.
-
-
- FUTURE DIRECTIONS OF C++
- _________________________________________________________________
-
- An ANSI committee has been formed to write an ANSI standard for
- C++. They first met in the Spring of 1990 and are expected to
- complete the standard in about three years. Until the new standard
- is released, the C++ language is expected to stay fairly stable.
- However, due to the nature of compiler writers and their desire to
- slightly improve their offerings over their competitors, you can
- bet that the language will not remain static during this three year
- period.
-
- Many small changes have been added during the past year that barely
- affect the casual programmer, or even the heavy user of the
- language. You can be sure that the language will evolve slowly and
- surely into a very usable and reliable language. There are two
- areas, however, that should be discussed in a little detail because
- they will add so much to the language in future years. Those two
- topics are parameterized types and exception handling.
-
-
-
- FUTURE DIRECTIONS - PARAMETERIZED TYPES
- _________________________________________________________________
-
- Many times, when developing a program, you wish to perform some
- operation on more than one data type. For example you may wish to
- sort a list of integers, another list of floating point numbers,
- and a list of alphabetic strings. It seems silly to have to write
- a separate sort function for each of the three types when all three
- are sorted in the same logical way. With parameterized types, you
- will be able to write a single sort routine that is capable of
- sorting all three of the lists.
-
- This is already available in the Ada language as the generic
- package or procedure. Because it is available in Ada, there is a
- software components industry that provides programmers with
- prewritten and thoroughly debugged software routines that work with
- many different types. When this is generally available in C++,
- there will be a components industry for C++ and precoded, debugged
- and efficient source code will be available off the shelf to
- perform many of the standard operations. These operations will
- include such things as sorts, queues, stacks, lists, etc.
-
-
- Page 9-6
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
-
- Bjarne Stroustrup has announced that parameterized types, otherwise
- known as templates or generics, will be available in a future
- version of C++. He has presented a paper with details of one way
- to implement them, but this is only a suggestion, not a
- specification.
-
- Borland International has included templates in version 3.0 of
- Borland C++, and hopefully their implementation will be very close
- to the final definition of templates.
- The next three example programs will illustrate the use of
- templates with Borland's compiler, but may not work with other
- compilers.
-
-
- THE FIRST TEMPLATE
- _________________________________________________________________
-
- The example program named TEMPLAT1.CPP is the ================
- first example of the use of a template. This TEMPLAT1.CPP
- program is so simple it seems silly to even ================
- bother with it but it will illustrate the use of
- the parameterized type.
-
- The template is given in lines 4 through 8 with the first line
- indicating that it is a template with a single type to be replaced,
- the type ANY_TYPE. This type can be replaced by any type which can
- be used in the comparison operation in line 7. If you have defined
- a class, and you have overloaded the operator ">", then this
- template can be used with objects of your class. Thus, you do not
- have to write a maximum function for each type or class in your
- program.
-
- This function is included automatically for each type it is called
- with in the program, and the code itself should be very easy to
- understand.
-
- The diligent student should realize that nearly the same effect can
- be achieved through use of a macro, except that when a macro is
- used, the strict type checking is not done. Because of this and
- because of the availability of the inline method capability in C++,
- the use of macros is essentially non-existent by experienced C++
- programmers.
-
-
-
- A CLASS TEMPLATE
- _________________________________________________________________
-
- The example program named TEMPLAT2.CPP is a ================
- little more involved since it provides a TEMPLAT2.CPP
- template for an entire class rather than a ================
- single function. The template code is given in
- lines 6 through 16 and a little study will show
-
- Page 9-7
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
- that this is an entire class definition. The diligent student will
- recognize that this is a very weak stack class since there is
- nothing to prevent popping data from an empty stack, and there is
- no indication of a full stack. Our intent, however, is to
- illustrate the use of the parameterized type and to do so using the
- simplest class possible.
-
- In the main program we create an object named int_stack in line 25
- which will be a stack designed to store integers, and another
- object named float_stack in line 26 which is designed to store
- float type values. In both cases, we enclose the type we desire
- this object to work with in "<>" brackets, and the system creates
- the object by first replacing all instances of ANY_TYPE with the
- desired type, then creating the object of that type. You will note
- that any type can be used that has an assignment capability since
- lines 13 and 14 use the assignment operator on the parameterized
- type.
-
- Even though the strings are all of differing lengths, we can even
- use the stack to store a stack of strings if we only store a
- pointer to the strings and not the entire string. This is
- illustrated in the object named string_stack declared in line 27
- and used later in the program.
-
- This program should be fairly easy for you to follow if you spend
- a bit of time studying it. You should compile and run it if you
- have a compiler that will handle this new construct.
-
-
-
- REUSING THE STACK CLASS
- _________________________________________________________________
-
- The program named TEMPLAT3.CPP uses the same ================
- class with the template as defined in the last TEMPLAT3.CPP
- program but in this case, it uses the date class ================
- developed earlier as the stack members. More
- specifically, it uses a pointer to the date
- class as the stack member.
-
- Because class assignment is legal, you could also store the actual
- class in the stack rather than just the pointer to it. To do so
- however, would be very inefficient since the entire class would be
- copied into the stack each time it is pushed and the entire class
- would be copied out again when it was popped. Use of the pointer
- is a little more general, so it was illustrated here for your
- benefit.
-
- All three of the previous programs can be compiled and executed if
- you have a copy of Borland C++ version 3.0. Other compilers may
- not work with these programs since parameterized types are not yet
- a part of the C++ specification.
-
-
-
- Page 9-8
-
- Chapter 9 - Multiple Inheritance and Future Directions
-
-
- FUTURE DIRECTIONS - EXCEPTION HANDLING
- _________________________________________________________________
-
- A future version of C++ will have some form of exception handling
- to allow the programmer to trap errors and prevent the system from
- completely shutting down when a fatal error occurs. The Ada
- language allows the programmer to trap any error that occurs, even
- system errors, execute some recovery code, and continue on with the
- program execution in a very well defined way. Bjarne Stroustrup,
- working in conjunction with the ANSI-C++ committee, has announced
- that some form of exception handling will be implemented but he has
- not stated what form it would take as of this writing.
-
-
- WHAT SHOULD BE YOUR NEXT STEP?
- _________________________________________________________________
-
- Once again, we have reached a major milestone in C++ programming.
- With the ability to use inheritance, you have nearly all of the
- tools you need to effectively use the object oriented programming
- techniques of C++ and you would do well to stop studying again and
- begin programming. The only topic left with C++ is virtual methods
- which are used for dynamic binding or polymorphism. This will be
- covered in the next two chapters. The vast majority of all
- programming can be done without dynamic binding, and in attempting
- to force it into every program, you could wind up with an
- unreadable mess, so you should approach it slowly.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 9-9
-