Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Cognizant 500 Glen Pointe Center West Teaneck, NJ 07666 Ph: 201-801-0233 www.cognizant.com
TABLE OF CONTENTS
Introduction ................................................................................................................................5 About this Document..................................................................................................................5 Target Audience.........................................................................................................................5 Objectives ..................................................................................................................................5 Pre-requisite ..............................................................................................................................5 Session 1: Introduction ...............................................................................................................6 Learning Objectives ...................................................................................................................6 Programming Language.............................................................................................................6 Programming Paradigm .............................................................................................................6 Procedural Programming ...........................................................................................................7 Object-based Programming .......................................................................................................8 Object Oriented Programming ...................................................................................................9 Object Oriented Modeling: .......................................................................................................10 Unified Approach (UA) .............................................................................................................12 Object-Oriented Methodologies................................................................................................14 Introduction to C++ ..................................................................................................................15 Summary .................................................................................................................................16 Test your Understanding..........................................................................................................16 Session 3: Objects and Classes ...............................................................................................17 Learning Objectives .................................................................................................................17 Introduction ..............................................................................................................................17 Object Oriented Programming Concepts..................................................................................17 Structures vs Classes ..............................................................................................................26 Abstract Data Types ................................................................................................................26 Summary .................................................................................................................................27 Test your Understanding..........................................................................................................27 Session 5: Inheritance...............................................................................................................28 Learning Objectives .................................................................................................................28 Introduction ..............................................................................................................................28 Forms of Inheritance ................................................................................................................28 Visibility of Inherited Members .................................................................................................30
Page 2 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Page 3 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Page 4 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Introduction
Target Audience
In-Campus Trainees
Objectives
Introduced to Programming Languages Define Object Oriented Modelling Explain software development methodology using object oriented programming using C++ Define Object Terminologies Identify how a class is inherited from other class Define Virtual Function and Polymorphism Perform Overloading Operators Work with Templates and Exception Handling
Pre-requisite
Basics of Programming in C
Page 5 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Session 1: Introduction
Learning Objectives
After completing this session, you will be able to Define programming language and Programming paradigm Identify some of the approaches to systems development methodology Develop programs using Object oriented approach Explain evolution of C++
Programming Language
Language is a means of communication between two individuals. Different standards and vocabulary sets are available for different languages. Information is communicated using these standards and vocabulary set following the rules for framing sentences and paragraphs.
A programming language is a means of communication between a human being and a computer. This language is analogous to the English language. The instructions are framed using the words and rules that constitute the programming language. These instructions are converted into a form that is understood and executed by the computer. Eventually, a task is performed by a computer using a set of logically related instructions.
The term computer language is a more expansive and alternative term for the more commonly used term programming language. A language is said to support a style of programming if it provides facilities that makes it convenient (reasonably easy, safe, and efficient) to use that style. Thousands of different programming languages have been created, and new ones are created every year. For example, HTML is a markup language and a computer language, but traditionally it is not considered as a programming language.
Programming Paradigm
A programming paradigm is a model for designing and implementing a software system. This model uses the logical components of the language such as Interaction between data structures Operations applied to them
A programming language provides the linguistic means (keywords, program structure, etc.) and the extra-linguistic capabilities, namely standard libraries and programming environment, to support a specific programming paradigm. Usually, a given programming language is targeted for a specific application domain, for example, string manipulation, mathematical applications, simulations, web programming and so on. C++, however, is not confined to any specific application domain. Rather, it is a multi-paradigm language. In other words, C++ was designed to support a range of styles. No single language can support every style.
Page 6 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Procedural Programming
Procedural programming is a programming based on separation between functions(actions) and the data that they manipulate. In general, functions rely on the physical representation of the data types that they manipulate. This dependency is one of the most problematic aspects in the maintenance and extensibility of procedural software.
A procedural program is composed of one or more units or modules either user coded or provided in a code library. Each module comprises one or more procedures. Procedure can also be called a routine, function, subroutine, or method, depending on programming language. Procedural programming follows a top down approach. It means that the flow of the program will be from top to bottom. For example, C language can use procedural programming approach, Decide which procedures you want; Use the best algorithms you can find. For example, a set of items can be sorted using bubble sort or quick sort or heap sort. This procedural programming style is best suited for tiny and simple programs. Procedural programming code is easier to read and more maintainable. Hence developing code using procedural programming model is more flexible.
Disadvantages of Procedural Programming The following are major drawbacks of procedural programming: The procedural programming enables only a limited form of code reuse, which is, calling a function or using a common user-defined data structure The bond between the data structure and the functions that operate on data structure significantly reduces their latency of reusability Procedural programming languages provide a confined set of built-in data types. These data types cannot be extended Some languages do not support User-defined data types The lack of generalization and packing information to hide them enforce users to expose the implementation of the function
Page 7 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
The evolution of C++ is unique among programming languages. The backward compatibility with C is one of the strengths. It enables organizations and programmers to benefit from C++ without having to trash hundreds of millions of lines of working C code. Furthermore, C programmers can easily become productive in C++ even before they have fully mastered object-oriented programming.
Object-based Programming
The limitations of procedural programming have led researchers and developers to find better methods of separating implementation details from interfaces. Object-based programming enables them to create user-defined types. User-defined types can bundle data and meaningful operations in a single entity, which is called class. Classes also support information hiding, thereby separating implementation details. This separation ensures that changes in the design are localized to a single entity - the class implementation; the class users on the other hand, are not affected.
Characteristics of Object-based Programming In object-based programming, each user-defined class is a self-contained entity i.e. a class has both data and operations. These operations operate only on those data. Such a self-contained entity is neither derived from a more general type, nor does it serve as a base for other types. So this programming lacks acquiring characteristics from the user-defined class. This decreases the code reusability.
Advantages of Object-based Programming Object-based programming overcomes most of the shortcomings of procedural programming. Few advantages of object-based programming are: It localizes changes by allowing changes in a specific class It de-couples implementation details from the interface It supports user-defined types The Standard Library provides a rich set of abstract data types, including string, complex, and vector. These classes are designed to provide an abstraction for very specific uses, for example, character manipulations and complex numbers arithmetic.
Page 8 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Advantages of Object Orientated Programming The major advantages of object oriented programming model are: Several classes can be declared and related together in the form of a tree The class tree is dynamic and can grow The developed system can be enhanced without making major changes in the previously written code. That is, we can add new sub-systems altogether without affecting existing system We can promote the growth of the class tree by defining new, more specialized classes to perform the tasks your applications require. That is, we can build new classes using previously built classes, thus reusing the system as much as possible This reusability saves time, decreases cost and takes less time to build the software
What is an object? In general, any tangible thing which has some physical existence in the real world is called an object. An object in computer science is defined as real or abstract entity which contains data and operations performed on it. These data and operations are bound together to form an entity.
Page 9 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Attributes and Functions An object knows its attributes and it does its functions. For example, a Car object can be described as: I am a Car: Car is an object I know my manufacturer, cost, model, owner and color: They are attributes which describe objects state. They are represented by data type I can transmit gear, accelerate and stop: They are methods defining its behavior which spells out the way in which the data is manipulated An object can also be an abstract entity. For example, a customer instance and an account instance might be objects of a banking application. This banking application works with such instances. Other examples include: A window object is responsible for things like opening, sizing, and closing itself. Numbers, arrays, records, fields, files, forms etc. can also be identified as objects.
An object-oriented modeling is a way to develop software by building self-contained modules that can be more easily replaced, modified and reused. For example, a class called Polygon can be created with generic characteristics. Two other classes called Rectangle and Pentagon are created and related to Polygon in a hierarchy. Now, Rectangle is a polygon is the relationship between two classes. An object of rectangle is created with defined dimensions. This module of classes is self-contained, in the sense that all the classes in this module have their own properties and behaviors built-in them-selves.
Purpose of Modeling It enhances understandability It is inexpensive Manipulation of the model is much easier than manipulating a real system Models reduce complexity by separating those aspects that are unimportant from those that are important
Page 10 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Encouragement of good programming techniques o The object level abstraction and the focus on real world aspects of the system promote more clear design and implementation. For example, we can create any type of polygons from the class Polygon. This encourages the developer to look at problems in a different way. Promotion of reusability o Objects are reusable because they are modeled directly out of a real-world problem domain. Within a framework the class does not concern itself with the rest of the system. Furthermore, object orientation allows class to be built from each other and therefore differences and enhancement need to be designed.
Benefits of Object Orientation The object oriented approach benefits the software development in the following way: It improves the reusability of the software parts The quality of the software is increased and the maintenance is easier The object technology emphasizes modeling the real world and provides us with the stronger equivalence of the real worlds entities (objects) than other methodologies It facilitates implementation of a concept in a form which is very close to its original abstract description
Page 11 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Objects are grouped in Classes A Class is an Object Template. Each object is an instance of a class. Classes are used to distinguish one type of object from another. It is a set of objects that share a common structure and common behavior. The role of a class is to define the attributes and methods of its instances. The class car, for example, defines the property manufacturer and the behavior, accelerate. Each individual car object will have a value for this property, such as GM, TATA or MARUTHI and it can accelerate to a speed of 100 kmph.
The Object Oriented Approach The object oriented systems development consists of the following phases: Object-oriented analysis Object-oriented information modeling Object-oriented design Prototyping and implementation Testing, iteration and documentation
This approach encourages you to view a problem as a system of co-operative objects. So when developing an OO application, we need to identify What objects does the application need? What functionality should those objects have?
1. The first task in analysis is to find the class of objects that will compose the system. In the first level, we find the physical entities in the system such as individuals, organizations, machines and others which make the context of the real world system.
Page 12 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Use Case Use Case, is a name for a scenario to describe the user computer system interaction. It is used for understanding system requirements. The user can be a human being or a system. The usecase model captures the goal of the user and the responsibility of the system to its users.
The use case description must contain: How and when the use case begins and ends The interaction between the use case and its actors, including when the interaction occurs and what is exchanged How and when the use case will store data in the system Exceptions to the flow of events
A Use-Case Driven approach Object-oriented analysis use-case driven Object-oriented design Prototyping Component-based development Incremental testing
Object-Oriented Analysis Object oriented analysis concerns with determining the system requirements and identifying classes and their relationships that makes up an application.
Object-Oriented Design The goal of object-oriented design is to design the classes identified during the analysis phase. The classes are identified for designing the user interface and data access.
Page 13 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Component-based development (CBD) Component-based Development is an industrialized approach to the software development process. The application development moves from custom development to assembly of pre-built, pre-tested, reusable software components that operate with each other.
Rapid Application Development (RAD) Rapid Application Development uses set of tools and techniques that can be used to build an application faster than typically possible with traditional methods. RAD does not replace System Development Life Cycle but complements it, since it focuses more on process description and can be combined perfectly with the object-oriented approach.
Incremental Testing Software development and all of its activities including testing are iterative processes. If you wait until after development to test an application for bugs and performance, you could be wasting thousands of dollars and many hours of precious time.
Object-Oriented Methodologies
Many methodologies are available to choose from for system development.
Rumbaughs Object Modeling Technique (OMT) OMT describes a method for the analysis, design, and implementation of a system using an object-oriented technique. OMT consists of four phases, which can be performed iteratively: 1. Analysis: The results are objects and dynamic and functional models. 2. System design: The result is a structure of the basic architecture of the system. 3. Object design: This phase produces a design document, consisting of detailed objects and dynamic and functional models. 4. Implementation: This activity produces reusable, extendible, and robust code.
OMT Modeling OMT separates modeling into three different parts: 1. An object model, presented by the object model and the data dictionary. 2. A dynamic model, presented by the state diagrams and event flow diagrams. 3. A functional model, presented by data flow and constraints.
Page 14 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
The Booch methodology prescribes A macro development process A micro development process.
The Jacobson Methodologies The Jacobson methodologies (e.g., OOBE, OOSE, and Objectory) cover the entire life cycle and stress traceability between the different phases.
Introduction to C++
In 1979, a young engineer at Bell (now AT&T) Labs, Bjarne Stroustrup, started to experiment with extensions to C to make it a better tool for implementing large-scale projects. In those days, an average project consisted of tens of thousands of lines of code (LOC).
When projects leaped over the 100,000 LOC count, the shortcomings of C language became noticeably unacceptable. By adding classes to C, the resultant language C with classes could offer better support for object oriented concepts.
In 1983, several modifications and extensions had already been made to C with classes and the name C++ was coined. Ever since then, the ++ suffix has become a synonym for objectorientation.
Between 1985 and 1989, C++ underwent a major reform. Protected members, protected inheritance, templates, and a controversial feature called multiple inheritance were added to the language.
The American National Standards Institutions ANSI C committee used the C Programming Language by the authors, Kernighan and Ritchie as a starting point. In 1989, the standardization of C++ was established by the ANSI committee.
Page 15 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Page 16 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Learning Objectives
At the end of this session, you will be able to: Describe the concepts of objects and classes in object paradigm List the principles of object orientation Differentiate structure and class Create abstract data types
Introduction
Object Oriented Programming is a paradigm which is applied in a variety of languages. In a classical language like Pascal or C, data-structures and their procedures are grouped logically by the programmer. But in OOP, the language provides facility to group procedures with their data type. This produces a decomposition grouped around the types in a program. The programmer does not have to match up the right procedure with the right data-type. Instead, variables know which operations they implement. OOP is proving itself to be a better way to engineer software. OOP yields better decomposition and more opportunities for code reuse. These strengths are especially important for writing large programs, packaging up code into libraries for use by others, and programming in teams.
cout is an output stream object which is usually associated to the monitor. It is used to print text and variables to the monitor. cin is an input stream object which is associated with the keyboard. It enables the user to enter a value and store that value in a given variable.
Class The most basic concept in Object Oriented Programming is the class. A class is similar to a type in a typical programming language. It is a user-defined data type which bundles data members with member functions which will operate on that type. The class provides an interface and hides the complexities. The following Fig. 3.1 shows the definition of the class. A class is specified by a <classname> preceded by the class specifier.
Page 17 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Member functions
The following program 3.1 defines a class called Employee: Program 3.1 class Employee { private: char ename[20]; // Employee class declaration // private access specifier // ename, empno & deptno are data members
short int empno; char deptno; public: // public access specifier void get_employee_name(); // get_employee_name & get_deptno member functions char get_deptno(); }
are
In the class definition, Employee is the class name. Ename, Empno & Deptno are all private data members which are accessible only inside the class Employee. Get_employee_name & get_deptno are the member functions that bind the data members ename and deptno. The member function get_deptno gets the department number of an instance of the Employee class. The department number can be known only with this function. So it is obvious that the function get_deptno binds the data variable deptno.
Object An instance of a class is called an object. An object is a run-time value which belongs to a class. This run-time value is known as instance of that class. The classes are like types and the objects are like variables. The figure depicts three objects and their data and member functions.
Page 18 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
MyClass
MyObject2
MyObject3
where, balance is a variable of type int. Similarly you can define many objects of the same class as shown below Employee E1, E2;
Employee is the class. E1 & E2 are the two objects which are instantiated from that class. Both the objects share the common behaviors get_employee_name and get_deptno with the same or different ename, empno & deptno values
Page 19 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Object1
show_account_holder (Message)
Object2
Function Overloading The process of using the same name for two or more methods is called overloading. All such methods must have different types of parameters or different number of parameters or different order of parameters. The compiler is capable of resolving those methods at compile time and binds the implementation with the code. The return type of the method alone cannot determine the difference between the functions sharing the same name. For example, we can define two versions of a function to round a given number. First is defined as round(<number>) and the second as round(<number>,<digits>). The first version is defined to round the given number to two digits. The second version is defined to round the number to the given number of digits. The function name for both the functions are same.
Page 20 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
All the data and implementation code for an object should be entirely hidden behind its interface. The idea is that we can create an interface and, as long as that interface remains consistent, the application can interact with the objects. In the atomic view of an object (or a class), the variables are considered to be within the nucleus and surrounded by methods. In other words, the data variables and member functions are encapsulated (bundled together) within the object. Hiding details and providing common interfaces is called encapsulation, which is an analogy from making an object look like it's covered by a capsule. For example, in the Fig. 2.3 the account_holder data member is bound to the member function show_account_holder from within the object2. Purpose of Encapsulation Encapsulation and information hiding work together to isolate one part of the system from other parts. Thus, we allow the code to be modified. The bugs can be fixed without the risk of introducing unnecessary or unintended side effects. This is done with the help of access modifier, which can be applied to variables. So, the restriction can be applied in terms of users who are going to access that class.
The data members and member functions of a class can be protected inside the object with the help of the access specifiers. If the members are accessible from the client code then the code violates the encapsulation principle which leads to encapsulation leakage.
The benefit of object-oriented programming derives from the fact that encapsulation of data members and member functions within an object give the member functions the right to access the data members.
Constructors Constructor is a member function which provides a convenient way to define the initial state of a newly allocated object. A constructor is similar to a method excepting that it has no return type All constant data members are initialized here. A constructor is called whenever an object is defined or dynamically allocated. It is not invoked by the usual message passing manner The constructor always has the same name as the name of the class It can be overloaded with any number of any types of parameter list If no constructor is written explicitly for a class, then a default constructor is created by the compiler Constructors can be made as private We can have copy constructors which are used for creating a clone of an object
Page 21 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Destructors The destructor function is automatically called by the compiler whenever the memory of the object is reclaimed. Destructor is also a member function of the class. It is an accompaniment of the constructor. The name of the destructor function is ~classname. The destructor cannot take arguments and so it cannot be overloaded. Destructors cannot be declared as private. Destructor function can perform any clean up activities. If an object points to a dynamic memory, this can be freed when the object is removed from memory. For example, the program 3.2 defines a constructor method Truck for the class Truck taking two parameters color and maximum speed. It also declares the destructor for the same.
Program 3.2 class Truck { public: Truck(color c, int MaxSpeed); // Overloaded constructor function void accelerate(int speed); // Accelerate function void accelerate(int speed, int MaxSpeed); // Accelerate function overloaded ~Truck(); // Destructor }
Hierarchy Classes in object oriented programming are arranged in a tree form called Class Hierarchy. The Class which lies at top level node is the Super-class in the class tree. The Class which lies in next subsequent level nodes is Sub-class. The semantics of the hierarchy are that Classes have all the properties of their Super-classes. In this way the hierarchy is by design general towards the root and specific towards its leaves. This hierarchy helps add logic to a collection of classes. It also enables similar classes to share properties through a principle Inheritance. In C++, a base class is a synonym for super-class and derived class is a synonym for subclass.
Inheritance Inheritance is the process by which a class inherits the properties and functions of its superclasses. When an object receives a message, it checks for a corresponding function existence. If the function is found, then it is executed. Otherwise the function is searched up in the tree and if
Page 22 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Light Vehicle
Heavy Vehicle
Car
Fig 3.4: Class Hierarchy showing Inheritance Function Overriding A derived class can re-define a base-class member function by supplying with a new version of that function with the same signature. If the signatures are different, this would be function overloading rather than function overriding. When an object receives a message, it first checks for the availability of the function in this object. If it is not available, then it consults its super-class. This search continues till the base-class which lies in the top most level. If the object's class and its super-class both contain the function, the first method found in the hierarchy takes precedence. This is known as function overriding. This gives a class an easy way to intercept messages before they get to its super-class. The Fig.3.5 shows two classes HeavyVehicle and Truck. The class Truck is inherited from the class HeavyVehicle. The function get_vehicle_type is defined in the class HeavyVehicle and is redefined in the sub-class Truck. So when an object of Truck is created and if the function is invoked, the re-defined version of the function is called (overrides) and not the member of HeavyVehicle.
Page 23 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Fig 3.5: Function Overriding Polymorphism In object oriented approach, set of classes in an inheritance hierarchy can respond to a generic message. The ability of responding to such a message regardless of class type in a right way is called polymorphism. As a principle, the class type of an object can be determined either at compile time or at runtime. If it is determined at compile time, it is called static polymorphism. If the determination is postponed to runtime, it is known as dynamic polymorphism. C++ supports dynamic polymorphism using the virtual nature of the function. Access Specifiers C++ defines three access specifiers which control the visibility of the members. They are public, private and protected controls which can qualify data members and member variables. Public members are accessible from outside the class. Usually the member functions are declared as public. Private specifier is the fundamental mechanism used for incorporating data hiding capability. This type of members is accessed only from inside the class. In the common object oriented programming, the data members should not be qualified as public. That state variables should be made accessible only by the member functions of that class to interact with the object. Usually the data members are declared as private. Protected access specifier is specially meant for use in inheritance. It serves as a means for providing member access to the own class and inherited classes. This is an extension of private access specifier. For example, the Program 3.3 shows how the private and protected data members are used. This program defines a class Vehicle with a private member steeringtype and a protected member Vehicolor. A class Car is publicly derived from Vehicle. This class cannot use the steeringtype of Vechile because it is declared as private, but can use Vehicolor.
Page 24 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Dynamic Objects C++ supports creating objects of classes dynamically at runtime. These objects are allocated in the heap memory and can be referred using pointers. Pointer variables are used to store address of a variable. The variable value can be accessed by using this pointer variable.
The new is an operator which is used to allocate memory dynamically at run time. The delete is an operator which removes a pointer to an object and sweeps its memory. For example, the following Program 3.4 shows how it allocates and de-allocates memory using new and delete operators respectively.
Program 3.4 Vehicle *myVehicles; // a pointer to an Account object. myVehicles = new Vehicle[5]; // allocate memory and call the constructor ... delete [] myVehicles; // invoke the destructor clear the memory
Page 25 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Program 3.5 class document { int no_of_pages; // private by default public: void get_chapters(); }; struct doc { int no_of_pages; void get_chapters(); };
// public by default
An existing data type may have several pieces of data packaged together. For example, a float has an exponent, a mantissa, and a sign bit. We can tell it to do tasks such as add to another float or to an int, and so on because it has characteristics and behaviors. A user-defined data type is the one that you create as a class. These are commonly referred to as abstract data types.
Similarly, the definition of Stack creates a new data type. You can add push(<>) and pop() functions into Stack. You create one by saying Stack, just as you create a float by saying float f. A Stack also has characteristics and behaviors. Even though it acts like a real, built-in data type, we refer to it as an abstract data type, perhaps because it allows us to abstract a concept from the problem space into the solution space.
In addition, the C++ compiler treats it like a new data type, and if you say a function expects a Stack, the compiler makes sure you pass a Stack to that function. So the same level of type checking happens with abstract data types (sometimes called user-defined types) as with built-in types. For example, the code shown in the program 3.6 creates an abstract data type called Stack.
Page 26 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Summary
You can define the components of a class, member variables, and member functions. Encapsulation is a technique which binds data and functions. Inheritance is the process of deriving the features of the parent class. Polymorphism is the process of using one interface for multiple function implementations. Function overriding is taking precedence of a function invocation by sharing same function name in the hierarchy of inherited classes. Function overloading is sharing same function name with different arguments within the same class. Access specifiers are used to control the visibility of the members of the class. Constructors are used to allocate and initialize the members of the class. Destructors reclaim the memory which was allocated during object creation. Objects are created dynamically using new operator and de-allocated using delete operator. The difference between the structure and class is the default visibility. Abstract data type is a user-defined class which abstracts a concept.
2. Create a class called car with a private data member named speed and function member accelerate setting the speed. Create an object of this class and see what kind of compiler messages you get when you try to access the class member.
Page 27 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Session 5: Inheritance
Learning Objectives
After completion of this session, you will be able to: Explain the inheritance principle and its various types Create simple applications using inheritance List the ambiguity in inheritance Work with friend function and class
Introduction
The mechanism of deriving a new class from an existing class is called inheritance (or derivation). The existing class is referred to as the base class and the new class is called as derived class or subclass. All the related classes are shown using a class hierarchy diagram. Any object oriented system supports the concept of reusability. Inheritance is a form of software reusability. This reusability is achieved by creating new classes and reusing the properties and functions of the existing ones. The derived class is allowed to inherit some or all the features from the base class.
Forms of Inheritance
There are various forms of inheritance. If a class is derived from only one base class then this form of inheritance is called single inheritance. A class can also inherit features from more than one class. This is called multiple inheritance. The mechanism of deriving a class from another derived class is known as multilevel inheritance. These three forms of inheritance are shown in Fig.5.1.
D2Shape
Shape
Father
Mother
Square
2DShape
Child
Square
Page 28 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
private Shape
// private
derivation
members of D2Shape
class D2Shape: { // };
public Shape
// public
derivation
members of D2Shape
Page 29 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Table 5.1: Visibility of Members Derived class visibility Base class visibility Public derivation Private Protected Public Not inherited Protected Public Private derivation Not inherited Private Private Protected derivation Not inherited Protected Protected
class B
The Fig.5.2 gives the visual representation of the visibility of inherited members.
The program 5.2 demonstrates the visibility of the data members defined with different access specifiers.
Page 30 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Page 31 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
// Error: not accessible // Error: not accessible // Error: not accessible (C is private) // Error: not accessible // Error: not accessible // Error: not accessible (D is protected)
Single Inheritance
Fig.5.3 shows an example of single inheritance. In this example, the class Manager is derived from the base class Employee. The Manager class can inherit all or some of the properties and functions of Employee class. The arrow is pointing the base class. This shows that Manger is derived from Employee. This means that the Manager can inherit the features of Employee. For example, if the Employee has the properties ename and enumber with protected visibility, then the Manager class inherits those two properties.
Employee
Base Class
Manager
Derived Class
Program 5.3, defines a class Employee with ename and enumber as data members. It defines the member functions getdata and putdata. The class Manager is a publicly derived from the base class Employee. Therefore, manager inherits all the public members of employee and retains their visibility. Thus a public member of the base class employee is also a public member of the derived class manager. The base class data member which is declared as private can be accessed only through the member functions defined in that particular class, even if it is inherited by derived class. So, the private members of Employee cannot be inherited by Manager. Those members can be accessed through the member functions of class Employee.
Page 32 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
cout<<"\n Enter name :"; cin>>ename; cout<<"\n Enter Employee no :";cin>>enumber; } void putdata() { cout<<"\n Name: "<<ename; cout<<"\n Employee Number:"<<enumber; } }; class Manager : public Employee { private: char branch[size]; unsigned long div_code; public: void getdata() { employee::getdata(); cout<<"\n Enter Branch Name :"; cin>>branch; cout<<"\n Enter Division Code :";cin>>div_code; } void putdata() { employee::putdata(); cout<<"\n Branch Name :"; cout<<branch; cout<<"\n Division Code :";cout<<div_code; } }; // Manager class
Page 33 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Employee data: Name: Raja Employee Number:1000 Manager data: Name: Vikas Employee Number:2000 Branch Name :Bangalore Division Code :1256
Page 34 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Multilevel Inheritance
In the Fig. 5.4, three classes are defined, Student, Test and Result. Student is the base class. Test is derived from Student and Result is derived from Test. There are three levels in the class hierarchy. So it is called as Multilevel inheritance. Student
Test
The program 5.4 below defines a protected data member roll_no and public functions get_number and put_number. The variable is also accessible in the Test class which is derived from Student. The public members are visible from the client side. Class Test is publicly inherited from Student and adds its own properties sub1 and sub2 and functions get_marks and put_marks. Class Result is publicly inherited from Test and adds its own property total and the function display. The class Result is having all the properties and behaviors of classes Student, Test and itself. Program 5.4 class Student { protected: int roll_no; public: void get_number(int a) { the class roll_no=a; } void put_number( ); // First level derivation // member function definition inside
}; void student::put_number( ) { // member function definition outside the class cout<<roll_number :<<roll_no ; }
Page 35 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
//
mark1,mark2
and
roll_no
are
<<total;
student1.get_number(111); student1.get_marks(50,65); student1.display(); } Output roll_number: marks in sub1: marks in sub2: Total Marks:
111 50 65 115
Page 36 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Multiple Inheritance
Deduction Allowance
The Fig.5.5 shows the third form of inheritance. This is multiple inheritance. The class Salary is inherited from both classes Deduction and Allowance. So this type of inheritance is called multiple inheritance. The allowance and deduction of employee can be identified as classes in a given problem. The program 5.5 shows how multiple inheritance is implemented. The classes Allowance and Deduction are defined at the first level. These two classes define their own specific properties and specific behaviors. A class Salary is derived from both the classes Allowance and Deduction. This inheritance is shown as class Salary: public Allowance, public Deduction. So this class can acquire the features of both the base classes. Program 5.5 class Allowance { protected: float medical; float hra; float city; void getdata() { cout<<"enter medical allowance :";cin>>medical; cout<<"enter house rent allowance :";cin>>hra; cout<<"enter city allowance :";cin>>city; } void showdata() { cout<<"\n Medical allowance :";cout<<medical; cout<<"\n House rent allowance :";cout<<hra; cout<<"\n City allowance :";cout<<city; } };
// protected access
Page 37 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
void getdata() { cout<<"enter provident fund: ";cin>>prov_fund; cout<<"enter professional tax: ";cin>>prof_tax; } void showdata() { cout<<"\n Provident fund deduction: ";cout<<prov_fund; cout<<"\n Professional tax deduction: ";cout<<prof_tax; } }; class Salary : public Allowance, public Deduction // Salary inheriting from two classes { private: float basic; int da; float tot_allow; float tot_ded; float gross; float net; public: void getdata() { cout<<"enter basic salary: "; cin>>basic; cout<<"enter dearness allowance in percentage :"; cin>>da; allowance::getdata(); deduction::getdata(); } void salary_process() { tot_allow=medical+hra+city; tot_ded=prov_fund+prof_tax; // private access
gross=(((basic*da)/100)+basic)+tot_allow; net=gross-tot_ded; }
Page 38 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
----Salary Statement---Basic salary:12000 Dearness allowance(50%): 6000 Medical allowance :200 House rent allowance :600 City allowance :300 Provident fund deduction: 500 Professional tax deduction: 750 Total allowance: 1100 Total deduction: 1250 Gross salary (basic+da+tot_allow) Net salary (gross-tot_ded) :17850
:19100
Page 39 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
B1 ( ): base constructor B2 ( ): base constructor D ( ): derived constructor B2 ( ): virtual base constructor B1 ( ): base constructor D ( ): derived constructor B ( ): super base constructor D1 ( ): base constructor D2 ( ): derived constructor
Page 40 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
The program 5.6 illustrates the order of invocation of constructors and destructors while handling instances of a derived class.
Program 5.6 class Person { protected: int Pid; public: Person(int id) { cout<<"Person class constructor called"<<endl; Pid=id; } ~Person() { cout<<"Person class destructor called"<<endl; } }; class Teacher:public Person { protected: int Tid; public: Teacher(int pid,int tid):Person(pid) { cout<<"Teacher class constructor called"<<endl; Tid=tid; } ~Teacher() { cout<<"Teacher class destructor called"<<endl; } };
Page 41 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Page 42 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Ambiguity in Single Inheritance In the derived class, there can be functions that have the same name as that in the base class. So when we try to access that function from the derived class object, the compiler cannot resolve which of the functions to invoke either from the derived class or from the base class. This situation results in ambiguity. So, the compiler resolves the conflict by using the following rule. If the same member (data/function) exists in both base and derived class, the member in the derived class will be executed.
Program 5.7 class Person { public: void show() { cout<<"show from Person"<<endl; } }; class Teacher : public Person { public: void show() { cout<<"show form Teacher "<<endl; } }; class SchoolTeacher:public Teacher { public: void show() { cout<<"show from SchoolTeacher"<<endl; } };
Page 43 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
In the program 5.7, the invocation of the member function show() in the derived class overrides the base class member function show(). To invoke the base class show(), the scope resolution operator(::) can be used to call the right version of the required member function. The program 5.7 is modified as Program 5.8 in invoking the right member function. Program 5.8 class Person { public: void show() { cout<<"show from Person"<<endl; } }; class Teacher : public Person { public: void show() { cout<<"show form Teacher "<<endl; } }; class SchoolTeacher:public Teacher { public: void show() { cout<<"show from SchoolTeacher"<<endl; } };
Page 44 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Ambiguity in Multiple Inheritance The Program 5.9 shows how ambiguity in multiple inheritance is resolved. Consider a class Child is derived from two base classes Father and Mother. These two classes have functions with the same name. Then the objects of the Child class cannot access the required base class function because the functions are available in both Father and Mother classes. The compiler cannot resolve this conflict and results in ambiguity error. To avoid this ambiguity, the scope resolution operator(::) is used with the right function from the appropriate class.
Program 5.9 class Father { public: void show() { cout<< show from father class <<endl; } }; class Mother { public: void show() { cout<< show from mother class <<endl; } };
Page 45 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Friend Function
The concept of encapsulation and data hiding dictates that non-member functions should not be allowed to access an objects private and protected members. The policy is that if you are not a member you cannot access the member data and functions. Sometimes this feature leads to considerable inconvenience in programming. Imagine a situation when it is required that a function need to operate on objects of two different classes. During such times, a non-member function outside the class tries to access and manipulate the private and protected members of the class. In C++, this is achieved by using the concept of friend.
Member functions Accessibility The various categories of functions that have access to private and protected data members could be any of the following: a member function of a class a member function of a derived class a friend function of a class a member function of a friend class
Table 5.3: Accessibility of various functions over class members Function Type Class member Derived class member Friend Friend class member Access directly to Private Yes No Yes Yes Protected Yes Yes Yes Yes Public Yes Yes Yes Yes
Page 46 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Program 5.10 class Salary { .. public: ... friend void ComputeNewPay (int empid); }; //declaration
The function definition can be placed anywhere in the program like a normal C++ function. The function definition does not use either the keyword friend or the scope resolution operator.
Properties of a Friend function Friend function is not the member function of the class in which it is declared as friend Since it is not in the scope of the class, it cannot be called using the object of that class It can be invoked like a normal function without the aid of any object Unlike member functions, it cannot access the member names directly and has to use an object name and dot membership operator with each member name (e.g. Test.x). It can be declared either in the public or the private part of a class and usually, it has objects as arguments
Page 47 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
void main() { myclass m1; m1.setab(5,6); cout<<"sum is = "<<add(m1)<<endl; without object } Output sum is 11 // friend function is invoked
Page 48 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Page 49 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
<<"Minimum
is
10
Page 50 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Object composition
The two most common techniques for reusing functionality in object-oriented systems are class Inheritance and object composition.
In inheritance, if the class Car is derived from the class LightVehicle, it is said that Car is a kind of LightVehicle; the class Car has all the properties of LightVehicle in addition to the features of its own.
A commonly recurring situation is one where objects are used as data members in a class. The use of object in a class as a data member is referred to as object composition. Object composition is an alternative to class inheritance. This new approach takes a view that an object can be a collection of many other objects and the relationship is called has-a" relationship or containership. For example, let Car be a class and let Engine be also a class. The relationship between these two classes can be established as Car has engine this is illustrated in the Fig. 5.7.
Class Car
Class Engine {
..
.. };
Class Car
{ Engine e1; .. };
In case of inheritance (kind of relationship), the constructors of base class are first invoked before the constructor of the derived class. Whereas, in the case of has-a relationship, the constructor of the class Car is invoked first and then the object of Engine is created.
Page 51 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Page 52 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Virtual Function
A virtual function is a member function that is declared within a base class and re-defined by the derived class. When a class containing a virtual function is inherited, the derived class re-defines the virtual function to fit its own need. Virtual functions implement one interface, multiple methods principle. For example, in the Fig. 7.1, consider the shape classes Rectangle, Circle, Triangle derived from base class Shape. Although each class has its own Draw() function. The Draw() function for each shape is different. When drawing a shape, whatever the shape may be, it would be nice to be able to treat all these shapes generically as objects of the base class Shape. Then to draw any shape, we could simply call function Draw() of base class Shape and let the program determine dynamically which derived class Draw() function to use.
To enable this kind of behavior, we declare Draw() in the base class as a virtual function and we override this function in each of the derived classes to draw the appropriate shape. A virtual
Page 53 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Page 54 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Page 55 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Polymorphism
The term polymorphism is derived form two latin words. Poly means many and morphos means form. The ability for objects of different classes that are related by inheritance to respond differently to the same message is known as polymorphism. Polymorphism is categorized into two types. They are Static polymorphism Dynamic polymorphism Static polymorphism is exhibited using overloaded functions and dynamic polymorphism is exhibited using late binding of overridden functions. The need for polymorphism is that many function implementations can be referred to by using a single interface. The code in the main function need not be modified.
Page 56 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Binding
When the overloaded functions are invoked by the code in the main function, the compiler is able to bind the function implementation to the code instruction. This concept is called Binding. Consider a class hierarchy which represents the motor pumps. The WaterPump is the base class from which JetPump class and CompressorPump is derived. The following program 7.3 creates an inheritance class hierarchy. The base class is WaterPump having member variables and member functions. Two classes JetPump and CompressorPump are derived from this base class. Program 7.3 #include <iostream.h> class WaterPump { private: int horsepower; int wattage; char on; public: void Pump() { Horsepower=0; Wattage=0; On=0; } virtual void set_pump_off(); virtual int getwattage(); }; virtual void WaterPump::set_pump_off() { if (flag) on=0; } virtual int WaterPump::getwattage() { return wattage; } class JetPump:public WaterPump { public: virtual void set_pump_onoff(); virtual int getwattage(); };
Page 57 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
An object of JetPump is created and the member function set_pump_off is invoked. To call this function the compiler should know to which class this function belongs. It identifies that the method set_pump_off belongs to the class JetPump. Consider the following next set of statements. JetPump *jp; Jp=new JetPump; Jp->set_pump_off(0); The compiler will associate the set_pump_off() function with a JetPump class based on the type of the pointer. There is no ambiguity. Therefore the compiler associates the function with the class by identifying the type of the object or pointer that is used to invoke the function. This process of associating a function to an object is called binding.
Static Polymorphism
A member function can be overloaded in a class. Polymorphism involves binding of functions on the basis of number, type and sequence of their arguments. The various types of parameters are specified in the function declaration, and therefore the function can be bound to the calls at compile time. This form of association is called early binding or static binding. This is called early binding because the calls to those functions are resolved during compile time. Consider the program 7.4. This defines a class called Shape3D. This class declares length, breadth and height as data variables and two overloaded functions to find the volume of the shape. The first function gets one parameter length. This is used to find the volume of cube. The next function collects three parameters length, breadth and height. These two functions have same name volume. Consequently they are called overloaded functions. The first function call in the main function code clearly calls the volume function with one parameter and the next one calls volume with three parameters. So the compiler is able to differentiate the two functions and binds the correct implementation with the code. In other words, it can be understood as the two functions implementation is resolved during compilation.
Page 58 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Dynamic Polymorphism
A function is said to exhibit dynamic polymorphism when it exists in more than one form, and calls to its various forms are resolved dynamically when the program is executed. In this case, the calls are determined at run time and not at compile time. For example, in certain situations of programming, there may be a requirement to collect a list of WaterPumps which needs to be created. Since the objects are created dynamically, the type of the object may not be known during compilation. To handle this situation we use virtual function and reference to object variable to achieve dynamic polymorphism. In the code snippet below, the first line declares a reference variable wp of type WaterPump. The next statement assigns the derived class object JetPump WaterPump reference variable wp. The next instruction calls the set_pump_off function. Now the implementation of the set_pump is resolved as JetPumps function because of the virtual nature of the function. Eventually the function code is bound during run time. So the output for this instruction is from JetPumps function implementation. The next statement assigns the object of type CompressorPump to the base class pointer. Now the base class pointer is reset to point to CompressorPump. The last instruction calls the set_pump off function. The virtual nature of that function postpones the binding of function with the code to runtime. Ultimately, the function of the CompressorPump is called. WaterPump *wp; wp=new JetPump; wp->set_pump_off(0); wp=new CompressorPump; wp->set_pump_off(0);
Page 59 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Summary
Virtual functions implement - one interface, multiple methods philosophy When a class has pure virtual function, it is called abstract class Pure virtual function is defined by suffixing the virtual function with the symbol =0 The ability for objects of different classes that are related by inheritance to respond differently to the same message is known as polymorphism Static polymorphism involves binding of functions on the basis of number, type and sequence of their arguments A function is said to exhibit dynamic polymorphism when it exists in more than one form, and calls to its various forms are resolved dynamically when the program is executed
2. If a base class declares a function to be virtual, and the derived class also declares the same function without the term virtual, is it still virtual?
3. Write a program to implement the inheritance and polymorphism principles. Create a base class called Satellite. Derive a class called EduSat meant for educational purpose such as studying the geographical system of earth and solar system. Create another sub-class derived from Satellite and name it as CommSat. It is used for the communication purposes like video conferencing, digital communication. Test your classes.
Page 60 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Operator Overloading
C++ supports a set of operators for built-in types. For example, x = y+1; + operates both y and 1. Similarly, it is possible to define operators that work with classes. This definition is just like an ordinary function definition except that the name of the function consists of the keyword operator followed by the operator. That is the difference. It becomes a function like any other function, which is called by the compiler when it scans the appropriate pattern. Operator overloading is an important technique that has enhanced the power of extensibility of C++ leading to realize polymorphism. Operator overloading enhances the program readability without the loss of functionality. Unlike C, in C++, operators can also be overloaded explicitly to operate on operands of user-defined data types. For instance the statement, C3 = AddComplex(C1, C2); performs the addition of operands C1 and C2 belonging to the user defined data type and assigns result to C3 (which is also a user defined data type). In C++, by overloading the + operator, the above statement can be changed to an easily readable form. C3 = C1 + C2;
Function return type: primitive, void or user defined Keyword Operator to be overloaded Argument to Operator Function return type operator operatorSymbol ( ) { // body of operator function }
Page 61 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
ret-type class-name :: operator#(arg-list) { // body of function } Often, operator functions return an object of the class they operate on, but ret-type can be of any valid type. The # is a place holder for the operator to be overloaded. When you create an operator function, substitute the operator for the #. For example, if you are overloading the / operator, use the operator / in the place of #. void Complex::operator / (Complex T) { // body of function } When you are overloading unary operator, arg-list will be empty. When you are overloading binary operator, arg-list will contain one parameter. Generally a binary operator is overloaded with a single explicit argument.
Program 9.1: class index { private: int value; public: index ( ) { value=0; } int get_index() { return value ; } void next_index ( ) { value =value + 1; } };
Page 62 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
0 0 1 2
The function, next_index increments the index value by 1. Instead of using such functions, the operators like ++ (unary operator for increment) can be used to perform the same task. It enhances both program clarity and readability without the loss of functionality. The program 9.2 is a modified version of the above program. Program 9.2 class index { private: int value; public: index ( ) { value=0; } int get_index() { return value ; } void operator ++ ( ); }; void index :: operator ++ ( ) { value =value + 1; }
Page 63 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
0 0 1 2
invoke the overloaded operator ++ member function defined in the class index. void operator ++ ( ) // prefix or postfix operator
Consider the example program 9.3 involving operations on complex numbers to illustrate the concept of binary operator overloading.
Page 64 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
y1)
Page 65 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
c3 =
c1.Addcomplex(c2);
invokes the member function Addcomplex() of the c1 objects class and adds c2 to it and then the returned result object is assigned to c3. By overloading the + operator, this odd statement can be represented in the simplified form as follows.
c3 = c1 + c2; A modified version of the program 9.3 is shown below in program 9.4. Program 9.4 class complex { private: float x,y; public: complex() { } complex(float x1,float { x=x1;y=y1; } y1)
void show() { cout<< x<<" + j"<< y <<endl; } complex operator +(complex obj1); }; complex complex::operator + (complex obj1) { complex temp; temp.x=x+obj1.x; temp.y=y+obj1.y; return temp; }
Page 66 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
The program 9.5 creates a class index and defines a friend function operator ++. The friend function shows how the reference parameter is passed using index &i1.
Page 67 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Page 68 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
The program 9.6 shows the implementation of the friend operator + function taking two explicit arguments. Program 9.6 class Complex { private: float x,y; public: Complex() { } Complex(float x1,float { x=x1;y=y1; } void show() { cout<< x<<" + j"<< y <<endl; } friend Complex operator +(Complex obj1,Complex obj2); }; Complex operator + (Complex obj1,Complex obj2) { complex temp; temp.x=obj2.x+obj1.x; temp.y=obj2.y+obj1.y; return temp; } void main() { complex c1(2.5,2.5),c2(1.7,2.6); complex c3; clrscr(); c3=c1+c2; cout<<"C1 = ";c1.show(); cout<<"C2 = ";c2.show(); cout<<"C3 = ";c3.show(); }
y1)
Page 69 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Program 9.7 #include<iostream.h> #include<conio.h> #include<string.h> const int size =100; class String { char str[size]; public: String() { } String(char *s) { strcpy(str,s); } void show(); String operator + (String s); int operator < (String s); }; void String::show() { cout<<'\''<<str<<'\''; }
Page 70 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Page 71 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Operators cannot be overloaded There are few operators that cannot be overloaded. They are: :: . ?: sizeof ( ) .* Scope operator Membership operator Conditional Operator Sizeof operator Pointer-to-member operator
Summary
Operator overloading is one of the important feature of C++ language. It is called compile time polymorphism. Operator overloading is done with the help of a special function, called operator function, which describes the special task to an operator. Using overloading feature, we can add two user defined data types such as objects, with the same syntax, just as basic data types. We cannot overload operators ::, ., ? :, sizeof(), .* There limitation in overloading operators is that the operator functions must either be member functions (non-static) or friend functions. The overloading operator must have at least one operand that is of user-defined type.
Page 72 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
3. How many arguments are required in the definition of an overloaded unary operator?
4. State whether the following statements are TRUE or FALSE: a. Using operator overloading concept, we can change the meaning of an operator. b. Operator overloading works when applied to class objects only. c. When using an overloaded binary operator, the left operand is implicitly passed to the member function. d. Operator functions never return a value.
Page 73 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Introduction
Templates are patterns that are reusable. A template allows the construction of a family of template functions and classes to perform the same operations on different data types. A significant benefit of template is reusability of source code that eliminates redundant coding. Template support generic programming that allows developing reusable software components such as functions and classes supporting different data types in a single framework. For instance, operations such as sort, search, swap, etc., which support various data types can be developed as a template. A C++ function is normally designed to handle a specific data type.
The templates declared for functions are called function template and those declared for classes are called class template. They perform respective operations depending on the data type of the arguments passed to them.
Function Templates
There are several functions of considerable importance that have to be used frequently with different data types. The limitation of such functions is that they operate only on a particular data type. It can be overcome by defining that function as a function template.
A function template is also called as generic function. It is used to create a pattern that describes what a function will do, leaving the compiler to fill in the details as needed. The general format of a template function definition is as follows.
template <class Ttype> ret-type func-name (parameter list) { // body of the function }
The template keyword tells the compiler that the class definition that follows will manipulate one or more unspecified types. At the time the actual class code is generated from the template, those types must be specified so that the compiler can substitute them.
Page 74 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Program 11.1 template <class X> void swapargs (X &a, X &b) { // This is a function template X temp; // which works by reference temp = a; a = b; b = temp; } void main() { int i=10, j=20; double x=10.1, y=23.3; char a='x', b='z'; cout << "Original i, j: cout << "Original x, y: cout << "Original a, b: swapargs(i, j); // swap swapargs(x, y); // swap " << i << ' ' << j << '\n'; " << x << ' ' << y << '\n'; " << a << ' ' << b << '\n'; integers floats
swapargs(a, b); // swap chars cout << "Swapped i, j: " << i << ' ' << j << '\n'; cout << "Swapped x, y: " << x << ' ' << y << '\n'; cout << "Swapped a, b: " << a << ' ' << b << '\n'; } Output Original i, j: Original x, y: Original a, b: Swapped i, j: Swapped x, y: Swapped a, b:
10 x 20 23.3 z
20 10.1 z 10 10.1 x
23.3
In this program, the class X, X &a and X &b part of the declaration makes the function generic as far as the input type is concerned. X is the placeholder for data type. While invoking the swap function, if the value passed is of type char, then the character is substituted in place of X, and if data type int is used if an integer value is passed. The data type float is used if floating point value is passed.
Page 75 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Instead of developing different swap implementations one each for character, integer and float, the same template is used for all the three data type values. All the data types share the same template function swap(). However, the compiler creates three swap() functions internally each operating each of the data types char, int and float.
The program 11.2 shows the function template to find the maximum of given two data items.
Program 11.2 template <class T> T max(T a, T b) { // This is a function template return a>b ?a : b; // which works by value } void main() { char ch1,ch2; int i, j; float m, n; cout<<"enter two characters :"; cin>>ch1>>ch2; cout<<"enter two integer number :"; cin>>i>>j; cout<<"enter two float numbers :"; cin>>m>>n; cout<<"the maximum of cout<<"the maximum of cout<<"the maximum of } Output enter two characters : enter two integer number : enter two float numbers : the maximum of a ,b is the maximum of 5 ,7 is the maximum of 34.5 ,56.8 is "<<ch1<<" ,"<<ch2<<" is "<<max(ch1,ch2)<<endl; "<<i<<" ,"<<j<<" is "<<max(i,j)<<endl; "<<m<<" ,"<<n<<" is "<<max(m,n)<<endl;
a 5 34.5
b 7 56.8 b 7 56.8
Page 76 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
If the program has both function and function template with the same name, first the compiler selects the normal function, scans for the match with the requested datatype, otherwise, it creates a function using a function template. The program 11.3 defines a max() function and a max() function template. It shows when the normal function is invoked, and when the function template is used. Program 11.3 #include<iostream.h> #include<string.h> char *max( char *a, char *b) { return (strcmp( a, b) > 0 ?a : b); } template <class T> max(T a, T b) { // This is a function template which works by value return (a>b?a:b); } void main() { char ch1,ch2; char str1[20],str2[20]; int i,j; cout<<"Enter two characters :"; cin>>ch1>>ch2; cout<<"Enter two integer number :"; cin>>i>>j; cout<<"Enter two strings :"; cin>>str1>>str2; cout<<"The maximum of "<<ch1<<" ,"<<ch2<<" is "; cout<<(char)max(ch1,ch2)<<endl; //compiler invokes function template max cout<<"The maximum of "<<i<<" ,"<<j<<" is "; cout<<max(i,j)<<endl; //compiler invokes function template max cout<<"The maximum of "<<str1<<" ,"<<str2<<" is "; cout<<max(str1,str2)<<endl; //compiler invokes normal function max }
Page 77 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Output Enter two characters :a A Enter two integer numbers :10 20 Enter two strings :India China The maximum of a ,A is a The maximum of The maximum of 10 ,20 is 20 India ,China is India
The program 6.4 shows overloaded function templates for display() function.
Program 11.4 template <class T > void display( T data ) { cout<<data<<endl; argument }
//
single
template
template<class T> void display(T data, int count) { for(int i=0;i<count;i++) standard argument cout<<data<<endl; } // template and
Page 78 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
// invoke // invoke
Page 79 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
5 10 15 3.1415
When the functions are overloaded, you may have different actions performed within the body of each function. But a generic function must perform the same general action for all versions - only the data type is different.
These classes model generic classes which support similar operations for different data types. For example, a generic stack class can be created, which can be used for storing data of type integer, real, and double in turn reduces in creating a separate class for the above said item.
The syntax of declaring class templates and defining objects using the same is shown below.
Page 80 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
class Classname { Tl data1; // data items of template type T1,T2, .. Void func1 (T1 a, T2 &b) // functions of template arguments T1,T2 T func2 (T2 *x, T2 *y); };
Consider an example of a stack (modeling last-in-first-out data structure) to illustrate the need and benefits of class templates. The class declarations for stacks of type character, integer, and double would be as follows.
Program 11.6 const int SIZE = 10; // This creates the integer type stack class class intstack { private: int stck[SIZE]; int tos; public: intstack( ) { tos=0;} void push(int i); int pop(); }; // This creates the double type stack class class doublestack { private: double stck[SIZE]; int tos; public: doublestack( ) { tos=0;} void push(double i); double pop();
Page 81 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Template declaration enables substitution of code for all the three declarations of stacks with a single template class as shown in program 11.7 below.
Program 6.7 const int SIZE = 10; // Create a generic stack class template <class StackType> class stack { StackType stck[SIZE]; int tos; public: stack() { tos = 0; } void push(StackType ob); StackType pop(); }; // holds the stack // index of top-of-stack // initialize stack // push object on stack // pop object from stack
As shown in the program 11.7, the declaration of a generic class is similar to that of a generic function. The actual type of data stored by the stack is generic in the class declaration. The determination of the actual data type is deferred until an object of the stack class is declared. When a specific instance of stack class is declared, the compiler automatically generates all the functions and variables necessary for handling the actual data.
Page 82 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Program 11.8 // Create a generic stack class template <class StackType> class stack { StackType stck[SIZE]; int tos; public: stack() { tos = 0; } void push(StackType ob); // holds the stack / index of top-of-stack // initialize stack // push object on stack
StackType pop(); // pop object from stack }; // Push an object template <class StackType> void stack<StackType>::push(StackType ob) { if(tos==SIZE) { cout << "Stack is full.\n"; return; } stck[tos] = ob; tos++; } // Pop an object template <class StackType> StackType stack<StackType>::pop() { if(tos==0) { cout << "Stack is empty.\n"; return 0; // return null on empty stack } tos--; return stck[tos]; } void main( ) { // Demonstrate character stacks. stack<char> cs; // create character stack int i; cs.push('a'); cs.push('b'); cs.push('c'); cout<<"character stack :"<<endl; for(i=0; i<3; i++) cout << "Pop character stack: " << cs.pop() << "\n";
Page 83 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
double stack : Pop double stack : 3.3 Pop double stack : 2.2 Pop double stack : 1.1
In the program 11.8 three different types of stacks are declared for character, integer and double with the object names cs, is and ds respectively. The following code shows the object creation. stack <char> cs; //create character stack //create integer stack
The desired data type is given inside the angular brackets. By changing the type of data specified when stack objects are created, you can change the type of data stored in that stack. For example, by using the following declarations, you can create another stack that stores character pointers.
stack<char*> chrptrq;
Page 84 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Program 11.9 template <class Type1, class Type2> class myclass { Type1 i; Type2 j; public: myclass(Type1 a, Type2 b) { i = a; j = b; } void show() { cout << i << ' ' << j << '\n'; } }; void main() { myclass<int, double> ob1(10, 0.23); myclass<char, char *> ob2('X', programming."); ob1.show(); // show int, double ob2.show(); // show char, char * } Output 10 0.23 X Templates help in generic programming
"
Templates
help
in
generic
Implementing generic functions and classes is one of the powerful features that are used to minimize the program development time by reusing them.
Exception C++ can detect run-time errors but does not in general have any idea what to do about them. The user may know how to cope with such errors but cannot detect them. The notion of an exception is provided to help deal with such problems.
An exception is an object that is thrown from the site of the error while program is in execution. Such an exception can be caught by an appropriate exception handle designed to handle that particular type of error. This makes that code simpler to write since you are not constantly forced to check for errors. In addition, a thrown exception is unlike an error value that is returned from a function or a flag that is set by a function in order to indicate an error condition. Exceptions provide
Page 85 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Exceptions are of two kinds, namely synchronous exceptions and asynchronous exceptions. Errors such as array range checks and I/O belong to synchronous exceptions The errors that are caused by events beyond the control of the program such as keyboard interrupts and certain arithmetic errors are called asynchronous exceptions
This section will deal with the concept in handling synchronous exceptions. The purpose of the exception handling is to provide a mechanism to detect and report the exceptional circumstances in the program so that appropriate action can be taken. This process involves separate error handling code that performs the following tasks. 1. Identify the problem (Hit the exception) 2. Report that an error has occurred (Throw the exception) 3. Receive the error information (Catch the exception) 4. Take corrective actions (Handles the exception) The error handling code basically consists of two segments, One segment is used to detect error and to throw exceptions The second segment is to catch the exceptions and to take appropriate actions.
The control flow of the exception handling model is shown in Fig. 11.1.
Page 86 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
The catch block that catches an exception must immediately follow the try block that throws the exception. The general forms of these two blocks are shown below:
try { throw exception; // block of statements which detects and throws an exception } catch (type argument) { } // block of statements that handles the exception // catches exception
When the try block throws an exception, the program control leaves the try block and enters the catch statement of the catch block. Exceptions are objects used to convey information about a problem. The throw clause can be used to throw an exception explicitly. If the type of the object thrown matches the argument type in catch statement, the catch block is executed for handling the exception. If they do not match, the program is aborted with the help of default abort() function which is invoked by the compiler. When no exception is detected and thrown, the control is transferred to the statement that immediately follows the catch block. That is, the catch block is skipped.
Page 87 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Program 11.10 void main() { int age; cout<<"Enter your age: \n"; cin>>age; try { if(age!=0) { cout<<"Your age is " <<age<<"\n"; } else { // there is an exception throw(age); // throws int object // catches the exception
} catch (int i) {
cout<<"Exception caught : Invalid age "<<i<<"\n"; } } Output in the first run: Enter your age: 20 Your age is 20 Output in the second run: Enter your age: 0 Exception caught : Invalid age 0
The program 11.10 collects the age of the user. If the user enters the age 20, the program prints the age of the user. If the user enters an invalid age like 0, it is thrown as an exception int object. This exception is caught in the catch clause and is handled by the code in the catch clause. The exception handler prints the message Exception caught: Invalid age 0.
Most often, exceptions are thrown by functions that are invoked from within the try block. The point at which the throw block is executed is called the throw point. Once an exception is thrown to the catch block, control cannot return back to the throw point. This control flow is shown in Fig. 11.2.
Page 88 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Invokes Function
catch block Catches and handles an exception Fig 11.2: Flow of try, throw and catch
The operand object exception may be of any type, including constants. It is also possible to throw objects not intended for error handling. Generally the exception can also be thrown by a function.
Page 89 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Program 11.11 void divide (int x, int y, intz) { cout << " inside the function \n ; if ((x-y) !=0) { int R = z / (x y) ; cout<< " Result = << R << \n; // there is a problem // throw point } else { throw (x-y); } } void main() { try { Cout<< inside the try block \n; divide (20,10,30); // Invoke divide divide(30,30,60); // Invoke divide } catch (int i) { Cout<< caught the exception \n ; } } Output We are inside the try block Result = -3 We are inside the exception Caught the exception
This defines a function divide(). The throw clause is stated inside this function. The invocation of this function is from within a try block in the main function. This invocation calls the function divide() which may be the cause for throwing an exception. The exception is thrown in the case where the denominator (x-y) evaluates to 0. Since the function call is enclosed in a try block, the associated catch block catches this exception and handles.
Page 90 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
The type indicates the type of exception that the catch block handles. The parameter argument is an optional parameter name. Note that the exception handling code is placed between two braces. The catch statement catches an exception whose type matches with the type of catch argument. When it is caught, the code in the catch block is executed.
Due to mismatch, if an exception is not caught, abnormal program termination will occur. It is important to note that the catch block is simply skipped if the catch statement does not catch an exception.
try { // try block } catch (type1 argument) { // catch block1 } catch (type2 argument) { // catch block2 } catch (typeN argument) { // catch blockN }
Page 91 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
CatchAll Exceptions
In some situations, we may not be able to anticipate all possible type of exceptions. Therefore, we may not be in a position to design unique catch handlers to catch the appropriate one. In such situations we can force a catch statement to catch all exceptions instead of one certain type alone. This could be achieved by defining the catch statements as follows.
The program 11.12 shows how all types of exceptions are caught and handled.
Page 92 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Re-throwing an Exception
Having caught an exception, it is common for a handler to decide that it cannot completely handle the error. In that case, the handler typically does what can be done locally and then throws the exception again. Thus an error can be handled where it is most appropriate. If a handler decides to re-throw the exception caught without processing it, we may simply invoke throw without any arguments as shown below.
throw;
This causes the current exception to be thrown to the next enclosing try/catch sequence and is caught by a catch statement listed after that enclosing try block. Program 11.13 demonstrates the re-throw of an exception.
Program 11.13 void divide (double x, double y) { cout << Inside function \n; try { If( y == 0.0) throw y; else
// Throwing a double
cout<< Division = <<x/y << \n; } catch (double) // Catch a double { cout<< Caught double inside function\n; throw; } cout<<End of function \n\n; } // Re-throwing double
Page 93 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Exception Specifications
It is possible to restrict a function to throw only certain specified exceptions. This is achieved by adding a throw list clause as part of the function definition. This specifies that the function may throw only exceptions shown in the exception list. The general form of using an exception specification is:
The type-list specifies the type of exceptions that may be thrown. Throwing any other type of exception will cause abnormal program termination. If we wish to prevent a function from throwing any exception, simply make the type-list empty. That is, we define the following function in the function header line,
throw () ;
// Empty list
Page 94 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
else if( x == 1 ) throw x; // int else if ( x == -1) throw 1.0; cout<< End of function block \n; // double } void main() { try { cout<<Testing Throw Restrictions \n; cout << x == 0 \n; test(0); cout << x == 1 \n; test(1); cout << x == -1 \n; test(-1); cout << x == 2 \n; test(2); } catch (char c) { cout<< Caught a Character \n; } catch (int m) { cout<< Caught an Integer \n; } catch (double d) { cout<< Caught a Double \n; } cout<< End of try-catch system \n; }
Page 95 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Summary
Exceptions are peculiar problems that a program may encounter at run time. Exceptions are of two types, synchronous and asynchronous. C++ provides mechanism for handling synchronous exceptions. An exception is typically caused by a faulty statement in a try block. The statement discovers the error and throws it, which is caught by a catch statement. The catch statement defines a block of statements to handle the exceptions appropriately. When an exception is not caught, the program is aborted. A try block may throw an exception directly or invoke a function that throws an exception irrespective of location of the throw point, the catch block is placed immediately after the try block. We can place two or more catch blocks together to catch and handle multiple types of exceptions thrown by a try block. It is also possible to make a catch statement to catch all types of exceptions. We may also restrict a function to throw only a set of specified exceptions by adding a throw specification clause to the function definition.
3. Where would you normally expect to find such a statement? What if that statement appeared in a different part of the program?
Page 96 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
Glossary
Programming language a means of communication between a human being and a computer Programming paradigm a model for designing and implementing a software system Procedural programming a programming based on separation between functions (actions) and the data that they manipulate Object oriented programming model a programming way which views software in terms of objects rather than actions Object Real or abstract entity which contains data and operations performed on it. These data and operations are bound together to form an entity Model an abstract representation of a system, constructed to understand the system prior to building it. Most of the modeling techniques involve graphical languages Class an Object Template Use Case a name for a scenario to describe the user-computer system interaction Encapsulation a technique which binds data and functions Inheritance the process of deriving the features of the parent class Polymorphism the process of using one interface for multiple function implementations Function overriding taking precedence of a function invocation by sharing same function name in the hierarchy of inherited classes Function overloading sharing same function name with different arguments within the same class Access specifiers used to control the visibility of the members of the class Constructors used to allocate and initialize the members of the class Destructors reclaim the memory which was allocated during object creation new operator used to create objects dynamically delete Objects are reclaimed using this operator Abstract data type a user-defined class which abstracts a concept Single inheritance if a class is derived from only one base class Multiple inheritance if a class inherits features from more than one class Multilevel inheritance the mechanism of deriving a class from another derived class abstract class when a class has pure virtual function Static polymorphism the ability for objects of different classes that are related by inheritance to respond differently to the same message Static polymorphism a function exists in more than one form, and calls to its various forms are resolved dynamically when the program is executed Operator overloading define operators that work with classes Exceptions peculiar problems that a program may encounter at run time try discovers the error and throws it, which is caught by a catch statement catch defines a block of statements to handle the exceptions appropriately.
Page 97 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
References
Websites
http://web.onetel.net.uk/~anthony_w/cplusplus/intrototemplates.pdf http://cplus.about.com/od/introductiontoprogramming/a/cppbeginners.htm http://newdata.box.sk/bx/c/index.htm http://www.w3.org/Library/User/Style/Cpp.html http://www.mycplus.com/Programming-FAQ.asp?FAQID=80&CATE=1 http://www.cse.iitk.ac.in/users/hk/cs350/slides/oo.pdf http://www.cplusplus.com/ www.omgili.com/preview/ aHR0cDovL3d3dy54Ym9hcmQudXMvYmJiL3Nob3d0aHJlYWQucGhwP3Q9MzMxND k
Books
C How to Program - Introducing C++, Java by Deitel Object Oriented Systems Development by Ali Bahrami Object-Oriented Analysis & Design by Grady Booch The Complete Reference, Herbert Schildt Object oriented programming in Turbo C++, Robert Lafore The C++ Programming Language, Bjarne Stroustrup C++ Unleashed Thinking in C++, Bruce Eckel
Page 98 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected
STUDENT NOTES:
Page 99 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected