Download as pdf or txt
Download as pdf or txt
You are on page 1of 167

Object-Oriented Programming Concepts and C++ References

Object-Oriented Programming Concepts

© Aptech Ltd. Version 1.0 Page 1 of 166


Object-Oriented Programming Concepts and C++ References

Table of Contents

S# Session Page #
1. Session 1: Introduction to Object-oriented
Programming
 A Survey of Programming Techniques 3
2. Session 2: Object-oriented Design
 Object Oriented Analysis and Design - Course 8
Notes
 Introducing UML: Object-Oriented Analysis and 9
Design
3. Session 3: Classes and Methods
 Classes, Objects and Methods 11

 Example of a Class variable (Static variable) 17


4. Session 4: Abstraction and Inheritance
 Object Oriented Programming – Abstraction 19

 Inheritance and its Types 24


5. Session 5: Multiple Inheritance and Interfaces
 Multiple Inheritance in Java 27

 Interfaces 32
6. Session 6: Polymorphism
 Polymorphism 37

 Understanding Static & Dynamic Polymorphism 38


with Examples
7. Session 7: Overloading
 C++: OOP: Overloading << and >> 42

 OOP 5. Constructor Overloading - TimeOfDay 44


8. Session 8: Overriding
 Overriding, Overloading and Overhiding in OOP 47

 Overriding 49
9. Session 9: Polymorphic Variable
 Static and Dynamic Behavior 51
10. Session 10: Generics
 Templates 56

© Aptech Ltd. Version 1.0 Page 2 of 166


Object-Oriented Programming Concepts and C++ References

S# Session Page #
11. Session 11: Frameworks and Reflection
 Struts 62
12. Session 12: Patterns
 Design Patterns 69

© Aptech Ltd. Version 1.0 Page 3 of 166


Object-Oriented Programming Concepts and C++ References

Session 1: Introduction to Object-oriented


Programming

A Survey of Programming Techniques


Source http://www.desy.de/gna/html/cc/Tutorial/node3.htm
Date of
Retrieval: 16/5/2012

Roughly speaking, we can distinguish the following learning curve of someone who learns to
program:

 Unstructured programming,
 procedural programming,
 modular programming and
 object-oriented programming.

This chapter is organized as follows. Sections 2.1 to 2.3 briefly describe the first three
programming techniques. Subsequently, we present a simple example of how modular
programming can be used to implement a singly linked list module (section 2.4). Using this
we state a few problems with this kind of technique in section 2.5. Finally, section 2.6
describes the fourth programming technique.

2.1 Unstructured Programming


Usually, people start learning programming by writing small and simple programs
consisting only of one main program. Here ``main program'' stands for a sequence of
commands or statements which modify data which is global throughout the whole program.
We can illustrate this as shown in Fig. 2.1.

Figure 2.1: Unstructured programming. The main program directly operates on global
data.

As you should all know, these programming techniques provide tremendous disadvantages
once the program gets sufficiently large. For example, if the same statement sequence is
needed at different locations within the program, the sequence must be copied. This has
lead to the idea to extract these sequences, name them and offering a technique to call and
return from these procedures.

© Aptech Ltd. Version 1.0 Page 4 of 166


Object-Oriented Programming Concepts and C++ References

2.2 Procedural Programming


With procedural programming you are able to combine returning sequences of statements
into one single place. A procedure call is used to invoke the procedure. After the sequence is
processed, flow of control proceeds right after the position where the call was made
(Fig. 2.2).

Figure 2.2: Execution of procedures. After processing flow of controls proceed where the
call was made.

With introducing parameters as well as procedures of procedures ( subprocedures)


programs can now be written more structured and error free. For example, if a procedure is
correct, every time it is used it produces correct results. Consequently, in cases of errors
you can narrow your search to those places which are not proven to be correct.

Now a program can be viewed as a sequence of procedure calls . The main program is
responsible to pass data to the individual calls, the data is processed by the procedures and,
once the program has finished, the resulting data is presented. Thus, the flow of data can
be illustrated as a hierarchical graph, a tree, as shown in Fig. 2.3 for a program with no
subprocedures.

Figure 2.3: Procedural programming. The main program coordinates calls to procedures
and hands over appropriate data as parameters.

To sum up: Now we have a single program which is devided into small pieces called
procedures. To enable usage of general procedures or groups of procedures also in other

© Aptech Ltd. Version 1.0 Page 5 of 166


Object-Oriented Programming Concepts and C++ References

programs, they must be separately available. For that reason, modular programming allows
grouping of procedures into modules.

2.3 Modular Programming


With modular programming procedures of a common functionality are grouped together
into separate modules. A program therefore no longer consists of only one single part. It is
now devided into several smaller parts which interact through procedure calls and which
form the whole program (Fig. 2.4).

Figure 2.4: Modular programming. The main program coordinates calls to procedures in
separate modules and hands over appropriate data as parameters.

Each module can have its own data. This allows each module to manage an internal state
which is modified by calls to procedures of this module. However, there is only one state per
module and each module exists at most once in the whole program.

2.4 Object-Oriented Programming


In contrast to the other techniques, we now have a web of interacting objects, each house-
keeping its own state (Fig. 2.6).

Figure 2.6: Object-oriented programming. Objects of the program interact by sending


messages to each other.

© Aptech Ltd. Version 1.0 Page 6 of 166


Object-Oriented Programming Concepts and C++ References

Consider the multiple lists example again. The problem here with modular programming is, that you must
explicitly create and destroy your list handles. Then you use the procedures of the module to modify each
of your handles.

In contrast to that, in object-oriented programming we would have as many list objects as needed.
Instead of calling a procedure which we must provide with the correct list handle, we would directly send
a message to the list object in question. Roughly speaking, each object implements its own module
allowing for example many lists to coexist.

Each object is responsible to initialize and destroy itself correctly. Consequently, there is no longer the
need to explicitly call a creation or termination procedure.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 7 of 166


Object-Oriented Programming Concepts and C++ References

Session 2: Object-oriented Design


Object Oriented Analysis and Design - Course Notes

Source http://www.freetechbooks.com/object-oriented-analysis-and-design-course-
notes-t577.html
Date of
Retrieval: 16/5/2012

Object modelling is useful for designing computer systems, whether those systems are to be
implemented in object-oriented languages or not. Most designs are likely to need more than
an object-oriented language, such as a database. Therefore, do not think that this is a
wasted exercise if you cannot convince your manager to let you use C++, Smalltalk or
whatever flavour of the month language is out there.

Object modelling also has a use outside of the design of computer systems. It is an
excellent analysis method, and it can be used in business process reengineering, in social
science research, or any complex environment where it is important to capture the structure
and functionality of some world.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 8 of 166


Object-Oriented Programming Concepts and C++ References

Introducing UML: Object-Oriented Analysis and


Design

Source http://www.devshed.com/c/a/Practices/Introducing-UMLObjectOriented-
Analysis-and-Design/
Date of
Retrieval: 16/5/2012

The purpose of UML, or Unified Modeling Language, is communication; to be specific, it is to


provide a comprehensive notation for communicating the requirements, architecture,
implementation, deployment, and states of a system. This article will offer an overview of
Object Oriented Analysis and Design, focusing in on the three most important concepts it
encompasses: objects, analysis, and design. It is excerpted from the book UML Applied: A
.Net Perspective, by Martin Shoemaker (Apress, 2004; ISBN: 1590590872).

Objects

Many modern programming languages depend largely or exclusively on the concept of


objects: a close syntactic binding of data to the operations that can be performed upon that
data. In these Object-Oriented languages—C++, C#, Java, Eiffel, Smalltalk, Visual Basic
.NET, Perl, and many others—programmers create classes, each of which defines the
behavior and structure of a number of similar objects. Then they write code that creates
and manipulates objects that are instances of those classes.

One reason why objects are a powerful programming technique—the reason most often
touted in the early literature on Object-Oriented Programming— is that programmatic
objects map naturally to real-world objects. Suppose, for example, that your company has
to deal with orders. These orders would probably have an ID number and contain
information on products. You could create Order objects, which would map to these real-
world objects, and which would have properties such as ID and ProductList. You’d
probably want to be able to add a product to the order and to submit the order, so you
could write AddProduct and SubmitOrder methods. This mapping between objects in the
real world and more abstract code objects encourages programmers to think in the problem
domain, rather than in computer science terms. This benefit has perhaps been overstated,
however; unless you’re building a simulator of a real-world process, such surrogate “real-
world” objects form just the surface of your system. The complexity of your design lies
underneath that surface, in code that reflects business rules, resource allocation,
algorithms, and other computer science concerns. If you only use objects to reflect the real
world, you leave yourself with a lot of work.

A more important benefit of classes and objects is that they form a nice syntactic
mechanism for achieving some classic aspects of well-designed code:2

Encapsulation. The goal of encapsulation is to expose only enough of a module or


subsystem to allow other modules to make use of it. Object-Oriented Programming allows
you to specify the degree of visibility of elements of your code, so that client code is
restricted in what it can access. Thus, you can syntactically seal off implementation details,
leading to more flexibility and maintainability in your system.

© Aptech Ltd. Version 1.0 Page 9 of 166


Object-Oriented Programming Concepts and C++ References

Loose coupling. Coupling refers to the ways in which and degrees to which one part of the
system relies on the details of another part. The tighter the coupling, the more changes in
one part of the system will ripple throughout the system. With loose coupling, the interfaces
between subsystems are well defined and restricted. What lies beyond those interfaces can
change without any changes needed in the client sub systems. Object-Oriented
Programming supports loose coupling by allowing you to define and publish a class’s
methods without publishing how those methods are carried out. This principle goes even
further in OO languages that support interfaces (described later in this section).

Strong cohesion. Cohesion refers to the degree in which elements within a subsystem
form a single, unified concept, with no excess elements. Where there is high cohesion, there
is easier comprehension and thus more reliable code. Object-Oriented Programming
supports strong cohesion by allowing you to design classes in which the data and the
functions that operate on them are tightly bound together.

Does OO force you to have these quality attributes in your code? I wish! No matter the
language, you can write shoddy code with no encapsulation, pathological coupling, and no
cohesion. Furthermore, some OO languages are less rigid than others in how much they
require you to design around objects. But OO languages certainly support these quality
attributes if you take the time to pursue them.

The key concepts in Object-Oriented Programming are these:

Classes. A class is the definition of the behavior and properties of one or more objects
within your system. A class binds the data (attributes) of an object to the behavior
(operations) that it can perform.

Attributes. An attribute is a data value or state that describes an object and helps you to
tell one object from another of the same class. It seems that every new OO language author
feels the need to distinguish their language by coming up with new terminology. In some
OO languages, these data values are called properties or member variables or member
data; but in UML, the proper term is attributes.

Operations. An operation is a behavior or function that an object can perform. Depending


on the OO language, these might be called methods or member functions or even
messages. The last term, messages, comes from Smalltalk, one of the earliest OO
languages, in which all objects communicated by sending messages to each other. You’ll see
a similar use of the term message when we study Sequence Diagrams.

Objects. An object is an instance or specific example of a class. If Dog is the class, then
Betsy, Ladi, Patches, Jake, Radar, and Frosty are specific instances of the class found in my
house. The attributes of the class have specific values within an object of that class; and the
operations of a class operate on the attributes of individual objects.

Inheritance. This concept indicates that one class (the superclass) provides some common
or general behavior inherited by one or more specific classes (the subclasses). The
subclasses then provide more or different behavior beyond that defined in the superclass.
For example, besides the Dogs, I have Cat objects and Horse objects that live on my
property. Each class has unique behaviors: Dogs must be walked, Cats use the litter box,
and Horses drop manure that must be scooped up and thrown in the manure pile. Yet all
classes have some common behavior: they must be fed, and they must have vet visits. So I
can define a superclass, Pet, and have my subclasses, Dog, Cat, and Horse, derive their

© Aptech Ltd. Version 1.0 Page 10 of 166


Object-Oriented Programming Concepts and C++ References

shared behavior from the Pet class. In UML, this concept is known under the slightly
different term of generalization, in which a superclass provides the generalized behavior of
the subclasses. It’s really the same concept, but just looking at it the other way up.

Components. A component is a collection of related classes that together provide a larger


set of services. Components in your system might include applications, libraries, ActiveX
controls, JavaBeans, daemons, and services. In the .NET environment, most of your
projects will require component development.

Interfaces. An interface is a definition of a set of services provided by a component or by a


class. This allows further encapsulation: the author of a component can publish just the
interfaces to the component, completely hiding any implementation details.

Each of these concepts will be explored in more detail as I discuss the UML diagrams that
represent them.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 11 of 166


Object-Oriented Programming Concepts and C++ References

Session 3: Classes and Methods

Classes, Objects, and Methods


Source http://caml.inria.fr/pub/docs/oreilly-book/html/book-ora140.html
Date of
Retrieval: 16/5/2012

Classes, Objects, and Methods


The object-oriented extension of Objective CAML is integrated with the functional and
imperative kernels of the language, as well as with its type system. Indeed, this last point is
unique to the language. Thus we have an object-oriented, statically typed language, with
type inference. This extension allows definition of classes and instances, class inheritance
(including multiple inheritance), parameterized classes, and abstract classes. Class
interfaces are generated from their definition, but may be made more precise through a
signature, similarly to what is done for modules.

Object-Oriented Terminology
We summarize below the main object-oriented programming terms.
class:
a class describes the contents of the objects that belong to it: it describes an
aggregate of data fields (called instance variables), and defines the operations
(called methods).
object:
an object is an element (or instance) of a class; objects have the behaviors of their
class. The object is the actual component of programs, while the class specifies how
instances are created and how they behave.
method:
a method is an action which an object is able to perform.
sending a message
sending a message to an object means asking the object to execute or invoke one of
its methods.
Class Declaration
The simplest syntax for defining a class is as follows. We shall develop this definition
throughout this chapter.
Syntax

class name p1 ...pn =


object
:
instance variables
:
methods
:
end

© Aptech Ltd. Version 1.0 Page 12 of 166


Object-Oriented Programming Concepts and C++ References

p1, ..., pn are the parameters for the constructor of the class; they are omitted if the class
has no parameters.

An instance variable is declared as follows:


Syntax

val name = expr


or
val mutable name = expr

When a data field is declared mutable, its value may be modified. Otherwise, the value is
always the one that was computed when expr was evaluated during object creation.

Methods are declared as follows:


Syntax

method name p1 ...pn = expr

Other clauses than val and method can be used in a class declaration: we shall introduce
them as needed.

Our first class example.


We start with the unavoidable class point:

 the data fields x and y contain the coordinates of the point,


 two methods provide access to the data fields (get_x and get_y),
 two displacement methods (moveto: absolute displacement) and (rmoveto: relative
displacement),
 one method presents the data as a string (to_string),
 one method computes the distance to the point from the origin (distance).

# class point (x_init,y_init) =


object
val mutable x = x_init
val mutable y = y_init
method get_x = x
method get_y = y
method moveto (a,b) = x <- a ; y <- b
method rmoveto (dx,dy) = x <- x + dx ; y <- y + dy
method to_string () =
"( " ^ (string_of_int x) ^ ", " ^ (string_of_int y) ^")"
method distance () = sqrt (float(x*x + y*y))
end ;;

Note that some methods do not need parameters; this is the case for get_x and get_y. We
usually access instance variables with parameterless methods.

After we declare the class point, the system prints the following text:

© Aptech Ltd. Version 1.0 Page 13 of 166


Object-Oriented Programming Concepts and C++ References

class point :
int * int ->
object
val mutable x : int
val mutable y : int
method distance : unit -> float
method get_x : int
method get_y : int
method moveto : int * int -> unit
method rmoveto : int * int -> unit
method to_string : unit -> string
end
This text contains two pieces of information. First, the type for objects of the class; this type
will be abbreviated as point. The type of an object is the list of names and types of methods
in its class. In our example, point is an abbreviation for:

< distance : unit -> unit; get_x : int; get_y : int;


moveto : int * int -> unit; rmoveto : int * int -> unit;
to_string : unit -> unit >

Next, we have a constructor for instances of class point, whose type is int*int -> oint. The
constructor allows us to construct point objects (we´ll just say ``points'' to be brief) from
the initial values provided as arguments. In this case, we construct a point from a pair of
integers (meaning the initial position). The constructor point is used with the keyword
new.

It is possible to define class types:


# type simple_point = < get_x : int; get_y : int; to_string : unit -> unit > ;;
type simple_point = < get_x : int; get_y : int; to_string : unit -> unit >

Note
Type point does not repeat all the informations shown after a class declaration. Instance
variables are not shown in the type. Only methods have access to these instance variables.

Warning
A class declaration is a type declaration. As a consequence, it cannot contain a free type
variable.

A Graphical Notation for Classes

We adapt the UML notation for the syntax of Objective CAML types. Classes are denoted by
a rectangle with three parts:

 the top part shows the name of the class,


 the middle part lists the attributes (data fields) of a class instance,
 the bottom part shows the methods of an instance of the class.

Figure gives an example of the graphical representation for the class caml.

© Aptech Ltd. Version 1.0 Page 14 of 166


Object-Oriented Programming Concepts and C++ References

Figure Graphical representation of a class.

Type information for the fields and methods of a class may be added.

Instance Creation
An object is a value of a class, called an instance of the class. Instances are created with
the generic construction primitive new, which takes the class and initialization values as
arguments.
Syntax
new name expr1 ...exprn

The following example creates several instances of class point, from various initial values.

# let p1 = new point (0,0);;


val p1 : point = <obj>
# let p2 = new point (3,4);;
val p2 : point = <obj>
# let coord = (3,0);;
val coord : int * int = 3, 0
# let p3 = new point coord;;
val p3 : point = <obj>

In Objective CAML, the constructor of a class is unique, but you may define your own
specific function make_point for point creation:

# let make_point x = new point (x,x) ;;


val make_point : int -> point = <fun>
# make_point 1 ;;
- : point = <obj>

Sending a Message
The notation # is used to send a message to an object. 2

Syntax

© Aptech Ltd. Version 1.0 Page 15 of 166


Object-Oriented Programming Concepts and C++ References

obj1#name p1 ...pn

The message with method name ``name'' is sent to the object obj. The arguments p1, ...,
pn are as expected by the method name. The method must be defined by the class of the
object, i.e. visible in the type. The types of arguments must conform to the types of the
formal parameters. The following example shows several queries performed on objects from
the class point.

# p1#get_x;;
- : int = 0
# p2#get_y;;
- : int = 4
# p1#to_string();;
- : string = "( 0, 0)"
# p2#to_string();;
- : string = "( 3, 4)"
# if (p1#distance()) = (p2#distance())
then print_string ("That's just chance\n")
else print_string ("We could bet on it\n");;
We could bet on it
- : unit = ()

From the type point of view, objects of type point can be used by polymorphic functions of
Objective CAML, just as any other value in the language:

# p1 = p1 ;;
- : bool = true
# p1 = p2;;
- : bool = false
# let l = p1::[];;
val l : point list = [<obj>]
# List.hd l;;
- : point = <obj>

Warning

Object equality is defined as physical equality.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 16 of 166


Object-Oriented Programming Concepts and C++ References

Example of a Class variable (Static variable)

Source http://www.roseindia.net/java/beginners/staticvariable.shtml
Date of
Retrieval: 16/5/2012

This Java programming example will teach you how you can define the static class variable
in a class. When a number of objects are created from the same class, each instance has its
own copy of class variables. But this is not the case when it is declared as static static.

static method or a variable is not attached to a particular object, but rather to the class as
a whole. They are allocated when the class is loaded. Remember, each time you call the
instance the new value of the variable is provided to you. For example in the class
StaticVariable each instance has different copy of a class variable. It will be updated each
time the instance has been called. We can call class variable directly inside the main
method.

To see the use of a static variable first of all create a class StaticVariable. Define one static
variable in the class. Now make a constructor in which you will increment the value of the
static variable. Now make a object of StaticVariable class and call the static variable of the
class. In the same way now make a second object of the class and again repeats the
process. Each time you call the static variable you will get a new value.

Code of this example is given below:

public class StaticVariable{


static int noOfInstances;
StaticVariable(){
noOfInstances++;
}
public static void main(String[] args){
StaticVariable sv1 = new StaticVariable();
System.out.println("No. of instances for sv1 : " + sv1.noOfInstances);

StaticVariable sv2 = new StaticVariable();


System.out.println("No. of instances for sv1 : " + sv1.noOfInstances);
System.out.println("No. of instances for st2 : " + sv2.noOfInstances);

StaticVariable sv3 = new StaticVariable();


System.out.println("No. of instances for sv1 : " + sv1.noOfInstances);
System.out.println("No. of instances for sv2 : " + sv2.noOfInstances);
System.out.println("No. of instances for sv3 : " + sv3.noOfInstances);
}

© Aptech Ltd. Version 1.0 Page 17 of 166


Object-Oriented Programming Concepts and C++ References

Output of the program is given below:

As we can see in this example each object has its own copy of class variable.

C:\java>java
StaticVariable
No. of instances for sv1
:1
No. of instances for sv1
:2
No. of instances for st2
: 2
No. of instances for sv1
:3
No. of instances for sv2
:3
No. of instances for sv3
:3

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 18 of 166


Object-Oriented Programming Concepts and C++ References

Session 4: Abstraction and Inheritance

Object Oriented Programming – Abstraction


Source http://www.mymindleaks.com/article/object-oriented-programming-
abstraction.html
Date of
Retrieval: 16/5/2012

Abstraction is a concept which facilitates to extract out the essential information of an


object.

In OOP ( Object Oriented Programming ) , Abstraction facilitates the easy conceptualization


of real world objects into the software program.

Abstraction lies everywhere! What ever you see, do and live are all full of abstraction.

In mathematics, multiplication is a kind of abstraction. The symbol "x" is an abstract


symbol that can do multiplication of any two elements.

2x3=6
3.5 x 3.7 = 12.95
(a + b) x ( a - b) = a^2 - b^2

In Art, Abstract Art is a kind of art, which depicts the distilled form of the world.

So, what exactly an Abstraction is?

Abstraction facilitates the easy conceptualization of real world objects, by eliminating the
unnecessary details of the object. Unnecessary details? Yes, all the similar objects when you
generalize, you will drop the uncommon details about the objects.

© Aptech Ltd. Version 1.0 Page 19 of 166


Object-Oriented Programming Concepts and C++ References

E.g., when you model a generic prototype for CRT Television & a Plasma Television, you
look for details like Type of screen, Height, Width, thickness etc.; these are necessary
details for a Television. But a Television object doesn't need to have details of what kind of
Electron it will bean to power the CRT, what kind of liquid plasmas it will use to power the
Plasma TVs. These kinds of details are unnecessary details.

Let's take mobile phone as the real world example. Look at the below mobile phones.

What do you feel about them?

 Firstly, everything is Nokia Mobiles


 You could see Slide, Flip and Bar models
 You could see Music, Business & 3G Mobiles
 You could see QWERTY , Basic and No keypads
 You could extra music player button on music edition.
 The Color, Size, Weight, Look etc...
 And even more…

So, for better understanding I organize the mobile phones in the below format.

Basically, all the mobiles belong to Nokia.

Still need a better classification, I drill down to its features and conceptualize the mobiles in
more general way. So, you could categorize the mobiles as

© Aptech Ltd. Version 1.0 Page 20 of 166


Object-Oriented Programming Concepts and C++ References

 Music
 Business
 Gaming
 Normal
 3G

As a layman user, you will feel its weight, color, style. As a music lover, you will check for
the memory, type of media files it supports, and type of communication between devices
(Bluetooth, Wi-Fi etc). As a business person, you will check for the memory, type of
business application etc.

Now, you have got the details of the each and every mobile. It's time to extract the most
essential details of these mobile categories. Here I use an Abstraction filter, which abstracts
out the essential details. So, essential details, here I mean is the most common properties
of the mobiles.

So, now the conceptualization of mobile has still got finer. Now you can still go deep and
get a finer concept to model a generic / abstract mobile, which can be turned into a
beautiful mobile of your kind.

© Aptech Ltd. Version 1.0 Page 21 of 166


Object-Oriented Programming Concepts and C++ References

Now, you have extracted out the necessary details for each category of mobile. You still fine
grain it to get a mobile phone's basic property with the Abstraction filter.

Now, here comes your basic design of the Nokia mobile phone. You have learnt how you will
abstract properties from the real world objects. Now the question is how you do it in the
programming language. In the Object oriented principles, abstraction is achieved via
Inheritance (a widely used design pattern)

The class diagram for the Nokia mobile using Inheritance look like below

© Aptech Ltd. Version 1.0 Page 22 of 166


Object-Oriented Programming Concepts and C++ References

You would have missed to understand the abstraction in the computer science. Here are few
places where you could see how the abstraction works

 Network Layers – OSI Model


 Database Architecture – Data Abstraction ( Physical, Logical , View )
 Polymorphism – Abstraction of Actions / Methods
 Templates in C++ or Java – Abstraction of Common Objects
 Data Structures – Abstract way to store & retrieve the data
 Many more…

One important thing you need to remember is 'Abstract objects' never exists in real world.
It is just the concept that we build to understand the working of real world objects.

E.g., There is nothing is called a Television, you have CRT Television (this is known
commonly as TV), Plasma TV or LCD TV.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 23 of 166


Object-Oriented Programming Concepts and C++ References

Inheritance and its Types


Source http://scienceray.com/biology/inheritance-and-its-types/
Date of
Retrieval: 16/5/2012

C++ is rich in its data types. Inheritance is the concept to inherit the properties of
one class to another class. This has also known as class structure again. For
example, classes A contains two-member function ads and subtracts and class b
contain two another functions multiply and divide.

Inheritance is the concept to inherit the properties of one class to another class. This has
also known as class structure again. For example, classes A contains two-member function
ads and subtracts and class b contain two another functions multiply and divide. We want to
use all these function with one object then we need to use inheritance where class B inherits
all the property of class, which is public, but class B cannot use the private properties of
class A. There are following types of inheritance:

1. Single class Inheritance:

When class a gas inherited in class has known as base class and B class is know as derived
class. Here only two classes have linked to each other.

© Aptech Ltd. Version 1.0 Page 24 of 166


Object-Oriented Programming Concepts and C++ References

2. Multilevel Inheritance:

In this type of inheritance, there are number of level and it has used in that cases where we
want to use all properties in number of levels according to the requirement. For example,
class A inherited in class b and class b has inherited in class c for class b so on. Where class
A is base class c. In another way we can say b is derived class a base class for c and a
indirect base class for c is indirect base class for c and c indirect derived class for class A.

3. Multiple Inheritances:

In this type of inheritance, n numbers of classes have inherited in a single class. Where two
or more classes are base class and one is derived class.

4. Hierarchical Inheritance:

This type of inheritance helps us to create a baseless for number of classes and those
numbers of classes can have further branches of n number of class.

© Aptech Ltd. Version 1.0 Page 25 of 166


Object-Oriented Programming Concepts and C++ References

5. Hybrid Inheritance:

In this type of inheritance, we can have mixture of number of inheritances but this can
generate an error of using same name function from no of classes, which will bother the
compiler to how to use the functions. Therefore, it will generate errors in the program. This
is known as ambiguity or duplicity.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 26 of 166


Object-Oriented Programming Concepts and C++ References

Session 5: Multiple Inheritance and Interfaces

Multiple Inheritance in Java


Source http://csis.pace.edu/~bergin/patterns/multipleinheritance.html
Date of
Retrieval: 17/5/2012

Introduction

Java was designed without multiple inheritance. While some developers think of this as a
flaw, it is actually true that the overall design of Java supports the solution of problems
commonly solved with multiple inheritance in other ways. In particular, the singly rooted
hierarchy (with Object as the ultimate ancestor of all classes) and Java interfaces solves
most problems that are commonly solved using multiple inheritance in C++.

However, there are a few situations in which multiple inheritance is very helpful. In this note
we will consider one special case and also the general case of multiple inheritance.

Mixin Inheritance

In mixin inheritance, one class is specifically designed to be used as one of the classes in a
multiple inheritance scheme. We say that it provides some functionality that is "mixed in" to
some other class that wants this functionality. Another way to think of mixin inheritance is
that a mixin class is given a new parent class so that the mixin seems to extend the other
class. In some projects it is necessary to rely on common services that must be provided by
several classes. Mixin inheritance is one way to centralize the development of these
services.

To provide for mixin inheritance we will need to define two interfaces as well a at least one
class that provides the service: the Mixin class. In some situations, one of these interfaces
is empty and may then be omitted.

The Interfaces

The first interface (always required) defines what the mixin class will provide for services. It
defines one or more methods that will be implemented by the mixin class. We will take a
simple and abstract example here. The class will be called (abstractly) MProvides to
emphasize that it defines what any compatible mixin must provide. We will also assume that
the only service provided is a void function and we will give it the abstract name func. In
practice, however, there may be any number of methods defined and they may have any
signatures.

interface MProvides
{ void func();
}

One special feature of mixin inheritance that is not usually present in the general multiple
inheritance case is that the mixin class may require services of the class into which it is

© Aptech Ltd. Version 1.0 Page 27 of 166


Object-Oriented Programming Concepts and C++ References

mixed. That is, in order to provide the "func" service, the mixin may need to get some
information from the other class. We define this with another interface. We will give it the
abstract name MRequires to indicate that it requires one or more services from the class
into which it is mixed.

Here we will suppose that the compatible mixins require that the other class provides a
method getValue that returns an int.

interface MRequires
{ int getValue();
}

In general, MRequires will have a more appropriate name and will have one or more
methods of arbitrary signature. However, any class into which we mix our mixin must
provide services with the given names and signatures, though it need not explicitly
implement the MRequires interface. If MRequires is empty it may be omitted.

The Mixin

The mixin class itself will implement the MProvides interface. It will also be created by
passing its constructor an argument that implements MRequires. Here is a simple example
called (again abstractly) Mixin.

class Mixin implements MProvides


{ public Mixin(MRequires parent) { this.parent = parent; }

public void func() { System.out.println("The value is: " + parent.getValue()); }

private final MRequires parent;


}

When a new Mixin is created it knows about an MRequires object. It can then query this
object using the services defined in MRequires in order to provide its own services. We have
called this object parent to emphasize that the intent is to simulate giving the Mixin class a
new parent class. If MRequires is empty, no object need be passed into the constructor.
Note that in general, the Mixin constructor may require other parameters as well.

The Class Used as the Base

Now suppose that we wish to mix this class into another class. This class must have all of
the methods required of the MRequires interface, but it need not implement this interface. It
will probably have other methods as well. Here is an example.

Class Parent
{ public P(int value ) { this.val = value; }
public int getValue() { return this.val; }

public toString() { return "" + this.val; }


private int val;
}

© Aptech Ltd. Version 1.0 Page 28 of 166


Object-Oriented Programming Concepts and C++ References

The Result of Mixing

Now, to actually mix the two classes together we first build a new class that extends Parent
and implements both of our interfaces

class Child extends Parent implements MRequires, MProvides


{
public Child(int value)
{ super(value);
this.mixin = new Mixin(this);
}

public void func(){ mixin.func(); }

private final MProvides mixin;

This class defines both the services of Parent and those of the mixin (MProvides). To
implement the Child class we create a new Mixin object and save it. We will also delegate all
messages defined in the MProvides interface to this object. When we create the Mixin object
we need to pass it an object that implements MRequires, but this object does so as this new
class implements the MRequires interface.

Note that the service named func is provided by the Mixin object as previously defined. It
does not need to be redefined in the Child class. Also note that the Child class automatically
implements MRequires since the inherited method fulfills the necessary contract defined by
the MRequires interface. We do have to provide the simple delegation function for the
method(s) of MProvides, however.

The key here is that we were able to design the Mixin class to be a mixin and so
define the two required interfaces. Note that it is actually the services defined by MProvides
that are mixed in, not, properly speaking, the Mixin class itself. This actually adds some
flexibility since several classes might implement this interface and so be mixed in to other
classes to provide this form of multiple inheritance.

General Multiple Inheritance

We can use the above to see how to provide general multiple inheritance. The difference
here is that we may not be able to design one of the classes to be a mixin. In the usual
case, the two classes are predefined and do not require services from each other. This
means that the MRequires interface is not needed. However, we still need to define one
interface, since Java won't let us mix two classes together.

If we do have the luxury of designing at least one of the classes then we can proceed as
before, treating that class as the mixin and defining an interface that it will implement.
Otherwise we need to do a bit more. Suppose that we would like to mix the class Parent of
the previous section with a class Other defined below.

© Aptech Ltd. Version 1.0 Page 29 of 166


Object-Oriented Programming Concepts and C++ References

Class Other
{
public Other(int value) { ... }

public void whatever()


{...
}
}

Since Java will let us extend only one class, we need to define an interface that declares the
public features of the other. We will do this to make our life simple here, though you may
choose to do the next step for the class of least importance and whose methods are going
to be called least often. Here we will define an interface to give the public methods of the
class Other.

Interface OtherInterface
{ void whatever();
}

We can now build a subclass of Other by doing nothing more than implementing this new
interface and providing any required constructors (which are not inherited).

class OtherChild extends Other implements OtherInterface


{ public OtherChild (int value){ super(value); }
}

If we had the freedom to modify class Other we could avoid the class OtherChild and just
have Other implement this new interface.

This new class is just like an Other, but it advertises that it implements the OtherInterface.
From here we can proceed as in the mixin case by extending the Parent class, implementing
he OtherInterface and creating a new OtherChild object to which we delegate the messages
defined in the OtherInterface.

Class ParentChild extends Parent implements OtherInterface


{ public ParentChild(...) { child = new OtherChild(...); ... }

public void whatever() { child.whatever(); }

private final OtherInterface child;


}

So, in this class we have merged the actual implementations of two other classes,
Parent and Other without modifying either class. This is general multiple inheritance. In
Java we needed to define and implement interfaces and use delegation to an object of one
of the classes to achieve this.

Conclusion

Multiple inheritance is needed only rarely. The fact that it is a bit awkward to achieve in
Java is not a disadvantage as it may discourage you from using it in those cases in which a

© Aptech Ltd. Version 1.0 Page 30 of 166


Object-Oriented Programming Concepts and C++ References

better solution is available. However, you should be aware that extensions to Java are not
necessary to achieve the use of most features that Java seems to lack. Rather the Java was
a good, sound, and complete language design that supports the kinds of things that
developers need. It takes skill, however, to see how to achieve some of the less used idioms
such as multiple inheritance.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 31 of 166


Object-Oriented Programming Concepts and C++ References

Interfaces
Source http://www.cs.utah.edu/~germain/PPS/Topics/interfaces.html
Date of
Retrieval: 17/5/2012

An interface is a description of the actions that an object can do... for example when
you flip a light switch, the light goes on, you don't care how, just that it does. In
Object Oriented Programming, an Interface is a description of all functions that an
object must have in order to be an "X". Again, as an example, anything that "ACTS
LIKE" a light, should have a turn_on() method and a turn_off() method. The
purpose of interfaces is to allow the computer to enforce these properties and to
know that an object of TYPE T (whatever the interface is ) must have functions called
X,Y,Z, etc.

Interfaces in Object Oriented Programming Languages

An interface is a programming structure/syntax that allows the computer to enforce certain


properties on an object (class). For example, say we have a car class and a scooter class
and a truck class. Each of these three classes should have a start_engine() action. How the
"engine is started" for each vehicle is left to each particular class, but the fact that they
must have a start_engine action is the domain of the interface.

The syntax of an Interface

An interface has a very simple syntax that looks very much like a class definition... public
interface XYZZY. Inside the {} of the interface is a list of functions that must be found in
any object that purports to "follow" the interface.

Interfaces are placed in their own files which have the same name as the interface (are
Capitalized) and end with the familiar language extension (e.g., ".as"). The following
interface would be placed in a "Vehicle.as" file.

Here is an example of the Vehicle interface referred to above (only a partial definition).

package
{
public interface Vehicle
{
// NO data VARIABLES are allowed in an interface

// only function PROTOTYPES

/**
* Comments...
* Anything that wants to be a "Vehicle" must, implement this function
*/

© Aptech Ltd. Version 1.0 Page 32 of 166


Object-Oriented Programming Concepts and C++ References

function start_engine() : void;

}
}
Below are enumerated the differences between an interface and a class.

1. No VARIABLES are allowed to be declared by the interface.

An interface is about actions that are allowed, not about data or implementation of
those actions.

2. The keyword public is not placed in front of the function prototypes. By definition,
all functions listed in an interface must be public functions.
3. There is no code after the function prototype. The normal {} are replaced with a
single semi-colon.

Implementing an Interface

To tell the computer that a new class that you are writing will fulfill all the requirements
(implement all the functions) of an interface, you must use the keyword implements in the
same location where you can use the keyword extends.

Here is an example of a Car Class which implements the Vehicle definition.

package
{
public class Car implements Vehicle
{

/**
* Comments...
*
* Here is how we start our car. This function is mandated by the Vehicle
* interface.
*/
function start_engine() : void
{
// code to start the engine of the car...
}

}
}

Remember: While all functions in the interface must be implemented in the class, you can
also create any other functions you want for that class.

© Aptech Ltd. Version 1.0 Page 33 of 166


Object-Oriented Programming Concepts and C++ References

Polymorphism applied to Interfaces

What is the power of the interface? The power is that once we have a number of classes
which implement the interface, from some point of view, they are equivalent. For example,
say we want to create a Car and a Truck, but all our program wants to do is "start" them
and "drive" them. To our program's "point of view" they are just Vehicles.

Below are examples showing how we would write the code without interfaces, with
interfaces, and then with a generic arrays of "Vehicles".

Without interface:

// Main Actions
var car : Car = new Car();
var truck : Truck = new Truck();

car.start_engine();
truck.start_engine();

car.drive();
truck.drive();

// Main Actions
var vehicle1 : Vehicle = new Car(); // here the only difference is the TYPE of eac
h variable is the same!!!!
var vehicle2 : Vehicle = new Truck();

vehicle1.start_engine();
vehicle2.start_engine();

vehicle1.drive();
vehicle2.drive();

// Main Actions
var vehicles : Array = new Array();

vehicles.push( new Car() ); // Assume our program is modeling a game or traffic s


imulation
vehicles.push( new Car() ); // The Cars and Trucks that we are modeling can be cr
eated in
vehicles.push( new Truck() ); // an arbitrary matter. Normally we would have to cr
eate separate
vehicles.push( new Car() ); // arrays for Cars, Trucks, etc. But because the are all
vehicles
vehicles.push( new Truck() ); // we can put them in a single array of Vehicle.
vehicles.push( new Truck() );
vehicles.push( new Truck() );
vehicles.push( new Car() );
vehicles.push( new Truck() );
vehicles.push( new Car() );

© Aptech Ltd. Version 1.0 Page 34 of 166


Object-Oriented Programming Concepts and C++ References

vehicles.push( new Bicycle() ); // assume Bicycle is also a Vehicle...


vehicles.push( new Car() );

// Later on in the program, we want to start all the cars...


// We can use GENERIC programming (we don't care if they are cars, trucks, bicycle,
etc, just that they are vehicles).

for each (var item : Vehicle in vehicles )


{
item.start_engine();
item.drive();
}

The final example above shows the concept of Polymorphism. Polymorphism is the idea
that an compile time (coding time) we don't know (and often can't know) what the actual
type of object inside a variable will be. In the vehicles array above, we don't know if
vehicles[i] is a car, truck, bicycle, etc. In computer languages without polymorphism, we
wouldn't be able to do anything with these objects.

With polymorphism, the computer remembers what each is and when we say:
"item.start_engine();" the computer decides, if this item is a truck then call
"truck.start_engine()", if this item is a car, call "car.start_engine()", if this object is an
XYZZY, call "XYZZY.start_engine();"

Polymorphism save the programmer a lot of time and effort in coding up "exceptional"
conditions. The computer does the work for us, a) remembering what each object really is,
and then b) at run time, invoking the actual function associated with the current object.

The specific Type under the Interface

Sometimes, you will want to use a function specific to an underlying type. For example, a
dump truck implements Vehicle, but additionally has a "raise_bed" function which dumps
everything out of the back of the truck. In the following code, the dump truck is thought of
by the computer as a Vehicle, and thus the code DOES NOT HAVE ACCESS to the
raise_bed function.

var vehicle : Vehicle = new Dump_Truck();

vehicle.start_engine(); // ALLOWED: vehicle is a Vehicle and thus has the start_engi


ne function
vehicle.drive(); // ALLOWED: vehicle is a Vehicle and thus has the start_engine
function

// Compile Time Type error


vehicle.raise_bed(); // NOT ALLOWED: while in reality (at run time) the vehicle var
iable
// will contain a Dump_Truck and thus this should be a lega
l
// operation, the compiler (at program time) only sees that
// vehicle is a Vehicle and the Vehicle class dose not

© Aptech Ltd. Version 1.0 Page 35 of 166


Object-Oriented Programming Concepts and C++ References

// have a raise_bed function.

But!!! you say, I (the programmer) know that this vehicle really is a Dump_Truck. How
can I tell this to the computer.

The as keyword.

To override the computers type checking, you can "take charge" of your program and force
the computer to treat the contents of the vehicle variable as a Dump_Truck. Here is the
proper code

var vehicle : Vehicle = new Dump_Truck();

(vehicle as Dump_Truck).raise_bed(); // ALLOWED: here the programmer overrid


es the type checking of the computer.

Warning: If the vehicle variable does not contain a Dump_Truck (the programmer made a
mistake), then the entire program will "Crash" at this point.

You should strive not to use the as key word except when absolutely necessary. When we
don't use it, we have the assurance of the computer that our types are correct. When we do
use it, all we have is the programmers assurance, and programmers are often wrong.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 36 of 166


Object-Oriented Programming Concepts and C++ References

Session 6: Polymorphism

Polymorphism
Source http://www.inf.ufsc.br/poo/smalltalk/ibm/tutorial/oop.html
Date of
Retrieval: 17/5/2012

Another benefit of separating implementaion from behavior is polymorphism. Polymorphism


allows two or more objects respond to the same message. A method called name could also
be implemented for an object of the class Course. Even though the implementation of this
name message may return a course number and a course title, its protocol is the same as
the name message to the Student object. Polymorphism allows a sending object to
communicate with different objects in a consistant manner without worrying about how
many different implementations of a message.

An analogy of polymorphism to daily life is how students response to a school bell. Every student knows
the significant of the bell. When the bell (message) rings, however, it has its own meaning to different
students (objects). Some students go home, some go to the library, and some go to other classes. Every
student responds to the bell, but how they response to it might be different.

Another example of polymorphism is the function of printing. Every printable object must know how to
print itself. The message is the same to all the different objects: print, but the actual implementation of
what they must do to print themselves varies.

The sending object does not have to know how the receiving object implements the message. Only the
receiving objects worries about that. Assume that there is a printPage method in a Document object that
has the responsibility of printing a page. To print the page, the printPage method sends the print
message to each object on the page. The Document does not need to know what types of objects are on
the page, only that each object supports the behavior of printing.

New objects can be added to the page without affecting the printPage method. This method still sends
the print message and the new object provides its own print method in response to that message.

Polymorphism allows the sending object to communicate with receiving objects without having to
understand what type of object it is, as long as the receiving objects support the messages.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 37 of 166


Object-Oriented Programming Concepts and C++ References

Understanding Static & Dynamic Polymorphism


with Examples
Source http://vishalnayan.wordpress.com/2011/03/01/understanding-static-dynamic-
polymorphism-with-examples/
Date of
Retrieval: 17/5/2012

Poly means many. So how can we take this definition in .NET context? Well we can apply
this to class’s ability to share the same methods (actions) but implement them differently.

Suppose we have a method in a class to add numbers,


public class calculation
{
public int add(int x, int y)
{
return x+y;
}
}
So to perform addition of three numbers, we need similar add method but with different
parameter
public class calculation
{
public int add(int x, int y)
{
return x+y;
}
public int add(int x, int y,int z)
{
return x+y+z;
}
}
So we can that class is sharing the same methods (actions) but implement them differently.
Now this is an example when we are sharing method name and implementing them
differently, let’s take a scenario where implementation is in some derived class.
For instance, say we create a class called Shape and this class has a method called .Area ()
which calculates area. Then we create two subclasses, using inheritance, of this Shape
class. One called Square, the other called Circle. Now obviously a square and circle are two
entirely different shapes, yet both classes have the .Area() method. When
the Square.Area() method is called it will calculate area of a square. When the Circle.Area()
method is called, it will calculate area of a circle. So both classes can use the same methods
but implement them differently.
Now let’s dive little deeper and understand what we discussed above in more technical
terms.
Types of Polymorphism

1) Static or Compile time Polymorphism


Which method is to be called is decided at compile-time only. Method Overloading is an
example of this. Method overloading is a concept where we use the same method name
many times in the same class, but different parameters. Depending on the parameters we

© Aptech Ltd. Version 1.0 Page 38 of 166


Object-Oriented Programming Concepts and C++ References

pass, it is decided at compile-time only. The same method name with the same parameters
is an error and it is a case of duplication of methods which c# does not permit. In Static
Polymorphism decision is taken at compile time.
public Class StaticDemo
{
public void display(int x)
{
Console.WriteLine(“Area of a Square:”+x*x);
}
public void display(int x, int y)
{
Console.WriteLine(“Area of a Square:”+x*y);
}
public static void main(String args[])
{
StaticDemo spd=new StaticDemo();
Spd.display(5);
Spd.display(10,3);
}
}

2) Dynamic or Runtime Polymorphism.

Run time Polymorphism also known as method overriding. In this Mechanism by which a call
to an overridden function is resolved at a Run-Time (not at Compile-time) if a base Class
contains a method that is overridden. Method overriding means having two or more
methods with the same name, same signature but with different implementation. In this
process, an overridden method is called through the reference variable of a superclass, the
determination of the method to be called is based on the object being referred to by
reference variable.

Class BaseClass
{
Public void show ()
{
Console.WriteLine(“From base class show method”);
}
}
Public Class DynamicDemo : BaseClass
{
Public void show()
{
Console.WriteLine(“From Derived Class show method”);
}
Public static void main(String args[])
{
DynamicDemo dpd=new DynamicDemo ();
Dpd.show();
}
}

Here memory allocation will be at the run time for that particular method.

© Aptech Ltd. Version 1.0 Page 39 of 166


Object-Oriented Programming Concepts and C++ References

What is Virtual Function: They implement the concept of polymorphism are the same as
in C#, except that you use the override keyword with the virtual function implementation
in the child class. The parent class uses the same virtual keyword. Every class that
overrides the virtual method will use the override keyword.
Why to use them:
1) It is not compulsory to mark the derived/child class function with Override KeyWord
while base/parent class contains a virtual method
2) Virtual methods allow subclasses to provide their own implementation of that method
using the override keyword
3) Virtual methods can’t be declared as private.
4) You are not required to declare a method as virtual. But, if you don’t, and you derive
from the class, and your derived class has a method by the same name and signature, you’ll
get a warning that you are hiding a parent’s method
5) A virtual property or method has an implementation in the base class, and can be
overriden in the derived classes.
6) We will get a warning if we won’t use Virtual/New keyword.
7) Instead of Virtual we can use New Keyword

class A
{
public void M()
{
Console.WriteLine(“A.M() being called”);
}
public virtual void N()
{
Console.WriteLine(“A.N() being called”);
}
}
class B : A
{
public new void M()
{
Console.WriteLine(“B.M() being called”);
}
public override void N()
{
Console.WriteLine(“B.N() being called”);
}
}
say
A a = new B();
a.M();
a.N();
The results would be
A.M() being called
B.N() being called

Override Keyword: method overriding is modifying or replacing the implementation of the


parent class with a new one. Parent classes with virtual or abstract members allow derived
classes to override them.

© Aptech Ltd. Version 1.0 Page 40 of 166


Object-Oriented Programming Concepts and C++ References

class Shape
{
public virtual void Draw()
{
Console.WriteLine(“Shape.Draw”) ;
}
}
class Rectangle : Shape
{
public override void Draw()
{
Console.WriteLine(“Rectangle.Draw”);
}
}

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 41 of 166


Object-Oriented Programming Concepts and C++ References

Session 7: Overloading

C++: OOP: Overloading << and >>

Source http://www.fredosaurus.com/notes-cpp/oop-friends/overload-io.html
Date of
Retrieval: 17/5/2012

Perhaps the most common use of friend functions is overloading << for I/O. This example
overloads << (ie, defines a operator<< function) so that Point objects can use cout and
<<.
// example usage
Point p;
...
cout << p; // not legal without << friend function.
Declare before public and private in header file
Declare friend functions outside the public and private sections of the header file. Often
they are placed first as in the example below.
//=== Point.h file =============================
class Point {
friend ostream& operator<<(ostream& output, const Point& p);
public:
...
private:
...
Definition
The definition of the operator<< function can be in any file. It is not a member function, so
it is defined with two explicit operands. The operator<< function must return the value of
the left operand (the ostream) so that multiple << operators may be used in the same
statement. Note that operator<< for your type can be defined in terms of << on other
types, specifically the types of the data members of your class (eg, ints x and y in the Point
class).
//=== Point.cpp file ===========================
...
ostream& operator<<(ostream& output, const Point& p) {
output << "(" << p.x << ", " << p.y <<")";
return output; // for multiple << operators.

© Aptech Ltd. Version 1.0 Page 42 of 166


Object-Oriented Programming Concepts and C++ References

}
Notational practice
The following are identical. First using traditional operator notation.
Point p, q;
cout << p << q;
This can be written with parentheses to show the order of evaluation. This makes it clearer
that the first operation has a result that is used by the second output operation.
((cout << p) << q);
An equivalent way is to write this using function for << is
operator<<(operator<<(cout, p), q);
Friend functions are not always needed
If there is no need to reference private data members, operator<< doesn't need to be a
friend function; it can be a function that isn't associated with the class in any way.
Defining >> for input
>> can be defined in a similar way.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 43 of 166


Object-Oriented Programming Concepts and C++ References

OOP 5. Constructor Overloading - TimeOfDay

Source http://www.leepoint.net/JavaBasics/oop/oop-45-constructor-overloading.html
Date of
Retrieval: 17/5/2012

Overloading constructors

It's common to overload constructors - define multiple constructors which differ in number
and/or types of parameters. For example, exact hours are common, so an additional
constructor could be defined which takes only the hour parameter. You can then set to
minutes to a default value.

// File : oop/timeofday/TimeOfDay1c.java
// Purpose: A time-of-day class with constructor, which provides
// a more convenient and conventional way to build objects.
// The constructor is overloaded (more than one version) for
// more convenience.
// Author : Fred Swartz, 2005-05-04, Placed in public domain.

public class TimeOfDay1c {


public int hour;
public int minute;

//====================================================
constructor
public TimeOfDay1c(int h, int m) {
hour = h;
minute = m;
}

//====================================================
constructor
public TimeOfDay1c(int h) {
hour = h;
minute = 0; // Set minutes to 0.
}
}

Calling one constructor from another using "this(...)"

Default parameters. It's very common for a constructor with fewer parameters to call a
constructor with more parameters, supplying default values. For this usage, the
constructors with fewer parameters will frequently consist of only the "this" call.

"this". Instead of calling the constructor with the class name, use the keyword this. The
compiler matches "this" with a constructor with the appropriate number and types of
parameters, and calls it.

© Aptech Ltd. Version 1.0 Page 44 of 166


Object-Oriented Programming Concepts and C++ References

Must be first. The "this" call must be the very first line of the constructor.

// File : oop/timeofday/TimeOfDay1d.java
// Purpose: A time-of-day class with overloaded constructors.
// One constructor calls the other using "this".
// Author : Fred Swartz, 2007-02-27, Placed in public domain.

public class TimeOfDay1d {


public int hour;
public int minute;

//====================================================
constructor
public TimeOfDay1d(int h, int m) {
hour = h;
minute = m;
}

//====================================================
constructor
public TimeOfDay1d(int h) {
this(h, 0); // Call other constructor.
}
}
Hidden constructor call at the beginning of every constructor

The one essential way in which constructors differ from methods is that the first statement
of every constructor is either a call on the constructor for the superclass (using super) or a
call to another constructor in the same class (using this).

Hidden call. You normally don't see the super call because the compiler automatically
generates a call to the parameterless superclass constructor for you, but it's generated at
the beginning of every constructor which doesn't explicitly call another constructor.

public TimeOfDay1d(int h, int m) {


hour = h;
minute = m;
}

Is the same as.

public TimeOfDay1d(int h, int m) {


super(); // Call Object constructor.
hour = h;
minute = m;
}

© Aptech Ltd. Version 1.0 Page 45 of 166


Object-Oriented Programming Concepts and C++ References

"Copy" Constructors

Another reason to overload constructors is to provide a copy constructor, which builds an


object from the values of another object of the same class. [Note: Another way to do this is
to implement the clone() method.]

// File : oop/timeofday/TimeOfDay1d.java
// Purpose: A time-of-day class with overloaded constructors.
// Implements a copy constructor.
// Author : Fred Swartz, 2007-02-27, Placed in public domain.

public class TimeOfDay1e {


public int hour;
public int minute;

//====================================================
constructor
public TimeOfDay1e(int h, int m) {
hour = h;
minute = m;
}

//====================================================
constructor
public TimeOfDay1e(int h) {
this(h, 0); // Call other constructor.
}

//====================================================
constructor
public TimeOfDay1e(TimeOfDay1e other) {
this(other.hour, other.minute); // Call other constructor.
}
}

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 46 of 166


Object-Oriented Programming Concepts and C++ References

Session 8: Overriding

Overriding, Overloading and Overhiding in OOP

Source http://blog.the24news.com/2010/09/overriding-overloading-and-
overhiding.html
Date of
Retrieval: 17/5/2012

OOP (Object Oriented Programming) is an approach which has collection of standards, built
using objects (a combination of data members and method members in cooperation) to
prepare the blueprints of applications or to create computer program.

There are few terms which have great value while working with OOP. You must have to
keep in mind while using/applying those to crate the computer program.

Overriding: This term can be used while we are working with the one of the strong pillar of
the OOP, “Inheritance”. This feature of the OOP will enable the reusability of the code by
establishing the relation, inheritance, between classes. Override will allow you to create the
method with the same signature, defined in the parent class in the child calss. If in future
the method defined in the parent needs to be use or redefine in the child class, its possible
by using keyword ,”Overriding”. That method must be marked as a “Virtual” in the parent
class. Below is a simple example for the overriding.

Snippet 1.1: Overriding Demo

Class A
{
public virtual void foo1();
}

Class B: A //Inheritance
{
Public override void foo1();
}

Overloading: This is the very beautiful feature that allows implementing multiple methods
with the same name but with the different signature. With the following change in the
signature you can leverage/implement the overloading.

1) void foo1();
2) void foo1(int a); //ok: different parameter set
3) void foo1(string a, int b);//ok again
4) void foo1(string h, int t);//error same parameter set as previous method
5) int foo1(int g); //Can not overload with return type only

Overhiding: This is the technique which can be used to hide the parent method in child class
by using the new keyword. That means whatever definition parent method have, can be

© Aptech Ltd. Version 1.0 Page 47 of 166


Object-Oriented Programming Concepts and C++ References

changed by this approach. A completely different method will come in to the picture. It can
be achieved as below.

Snippet 1.2: Overhiding Demo

class A
{
public void foo1() { Console.WriteLine("foo1 from A"); }
}
class B : A
{
public new void foo1() { Console.WriteLine("foo1 from B"); }
}

Not Only methods in base classes need not override or hide derived methods. Every method
in derived classes requires to be either defined as new or as override.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 48 of 166


Object-Oriented Programming Concepts and C++ References

Overriding

Source http://chennaisunday.com/overriding.html
Date of
Retrieval: 17/5/2012

Overriding is nothing but a "Argument (or) signature must be same and return type
should be a covariant." .

An instance method in a subclass with the same signature (name, plus the number and the
type of its parameters) and return type as an instance method in the superclass overrides
the superclass's method.

The ability of a subclass to override a method allows a class to inherit from a superclass
whose behavior is "close enough" and then to modify behavior as needed. The overriding
method has the same name, number and type of parameters, and return type as the
method it overrides. An overriding method can also return a subtype of the type returned by
the overridden method. This is called a covariant return type.

Class Methods

If a subclass defines a class method with the same signature as a class method in the
superclass, the method in the subclass hides the one in the superclass.

The distinction between hiding and overriding has important implications. The version of
the overridden method that gets invoked is the one in the subclass. The version of the
hidden method that gets invoked depends on whether it is invoked from the superclass or
the subclass. Let's look at an example that contains two classes. The first is Animal, which
contains one instance method and one class method:

public class Animal {


public static void testClassMethod() {
System.out.println("The class method in Animal.");
}
public void testInstanceMethod() {
System.out.println("The instance method in Animal.");
}
}

The second class, a subclass of Animal, is called Cat:

public class Cat extends Animal {


public static void testClassMethod() {
System.out.println("The class method in Cat.");
}
public void testInstanceMethod() {
System.out.println("The instance method in Cat.");
}
public static void main(String[] args) {
Cat myCat = new Cat();

© Aptech Ltd. Version 1.0 Page 49 of 166


Object-Oriented Programming Concepts and C++ References

Animal myAnimal = myCat;


Animal.testClassMethod();
myAnimal.testInstanceMethod();
}
}

The Cat class overrides the instance method in Animal and hides the class method in
Animal. The main method in this class creates an instance of Cat and calls
testClassMethod() on the class and testInstanceMethod() on the instance.
The output from this program is as follows:

The class method in Animal.


The instance method in Cat.

As promised, the version of the hidden method that gets invoked is the one in the
superclass, and the version of the overridden method that gets invoked is the one in the
subclass.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 50 of 166


Object-Oriented Programming Concepts and C++ References

Session 9: Polymorphic Variable

Static and Dynamic Behavior


Source http://web.engr.oregonstate.edu/~budd/Books/oopintro3e/info/slides/chap11/all.htm
Date of
Retrieval: 17/5/2012

Static and Dynamic


In Programming languages:

 Static almost always means fixed or bound at compile time, and cannot thereafter be
changed.
 Dynamic almost always means not fixed or bound until run time, and therefore can
change during the course of execution.

Static and Dynamic Typing


In a statically typed programming language (Java or Pascal), for example, variables have
declared typed -- fixed at compile time.

In a dynamically typed programming language (Smalltalk or CLOS), a variable is just a


name. Types are associated with values, not variables. A variable can hold different types
during the course of execution.

Arguments for and Against


Static and Dynamically typed languages have existed as long as there have been
programming languages. Arguments for and against:

 Static typing allows better error detection, more work at compile time and hence
faster execution time.
 Dynamic typing allows greater flexibility, easier to write (for example, no declaration
statements).

Both arguments have some validity, and hence both types of languages will continue to
exist in the future.

The Polymorphic Variable


The addition of object-oriented ideas in a statically typed languages adds a new twist. Recall
the argument for substitution: an instance of a child class should be allowed to be assigned
to a variable of the parent class:
var
pet : Mammal;
fido : Dog;
felice: Cat;
begin
pet := fido; // legal

© Aptech Ltd. Version 1.0 Page 51 of 166


Object-Oriented Programming Concepts and C++ References

pet := felice; // legal


fido := pet; // not legal!

Static Class and Dynamic Class


In a statically typed language we say the class of the declaration is the static class for the
variable, while the class of the value it currently holds is the dynamic class.

Most statically typed OO languages constrain the dynamic class to be a child class of the
static class.

var
pet : Mammal;
fido : Dog
begin
pet := fido; // static class is Mammal, dynamic class is Dog
end;

Importance of Static Class


In a statically typed object-oriented language, the legality of a message is determined at
compile time, based on the static class.

A message can produce a compile error, even if no run-time error could possibly arize:

class Mammal { }
class Dog extends Mammal {
void speak() { System.out.println("woof"); }
}

Mammal pet = new Dog;


pet.speak(); // will generate error, Mammals don't speak

Reverse Polymorphism

Polymorphism says we can assign a value from a child class to an instance of the parent
class, but can this assignment then be reversed? Under what conditions?

var
pet : Mammal;
fido : Dog;
felice : Cat;
begin
pet := fido; // legal
fido := pet; // is this legal?
end;

This is known as the problem of reverse polymorphism.

© Aptech Ltd. Version 1.0 Page 52 of 166


Object-Oriented Programming Concepts and C++ References

Two aspects of reverse polymorphism

There are two specific problems associated with the question of reverse polymorphism.

 The problem of identity - can I tell if a value declared as an instance of a parent class
actually holds a value from a subclass.
 The task of assignment - can I then assign the value from the parent class to a
variable declared as the subclass.

In some languages mechanisms are provided to address these two problems together, while
in other languages they are separated.

The Container Problem

The task of reverse polymorphism is often encountered in connection with a collection of


values - we have a list of items from the parent class (say a list of Mammals), and when we
extract a value we need to know if it is a more specific type.

Generally occurs in languages with a single inheritance tree, where the only type we may
have associated with a value is the class ``Object''.

Solving this problem generally requires values to have ``self knowledge'' of their own type.
In some languages they do, in some languages values do not.

A case study examining one solution to the container class problem will be presented in a
later chapter.
Java, unfortunately, uses to term Container to mean a type of graphical component, and
not a collection class, as is common in most other languages.

Static and Dynamic Method Binding

Should the binding for information be associated with the static class of a variable or the
dynamic class.

Alice holds a small Mammal - asks Bill ``does this animal give birth to live young''.

Static answer - All mammals give birth to live young - therefore yes.

What if the Mammal is a platypus? Dynamic answer - Platypus lay eggs, therefore no.

Even statically typed OOP languages can use dynamic binding. But may use static type to
determine legality of operation.

Documenting Method Binding


In many languages dynamic binding is the default. If a child class overrides a method in the
parent, using the same type signature, then the selected method will be determined by the
dynamic type.

© Aptech Ltd. Version 1.0 Page 53 of 166


Object-Oriented Programming Concepts and C++ References

In other languages (C++, Delphi, C#) the programmer must indicate which methods are
dynamically bound and which are statically type. In C#, for example, this is done using the
virtual keyword.

class Animal {
public:
virtual void speak () { cout << "Animal Speak !\n"; }
void reply () { cout << "Animal Reply !\n"; }
};

class Dog : Animal {


public:
override void speak () { cout << "woof !\n"; }
void reply () { cout << "woof again!\n"; }
};

class Bird : Animal {


public:
virtual void speak () { cout << "tweet !\n"; }
};

Animal a;
Dog b;
b.speak();
woof !
a = b;
a.speak();
woof !
Bird c;
c.speak();
tweet !
a = c;
a.speak();
tweet !

Method Binding in C++


C++ is the most complex language. Not only must the programmer use the virtual
keyword, but true polymorphism only occurs with pointer or reference variables.
virtual void speak () { cout << "Animal Speak !\n"; }
void reply () { cout << "Animal Reply !\n"; }
};

class Dog : public Animal {


public:
virtual void speak () { cout << "woof !\n"; }
void reply () { cout << "woof again!\n"; }
};

class Bird : public Animal {


public:
virtual void speak () { cout << "tweet !\n"; }
};

© Aptech Ltd. Version 1.0 Page 54 of 166


Object-Oriented Programming Concepts and C++ References

Animal * a;
Dog * b = new Dog();
b->speak();
woof !
a = b;
a->speak();
woof !
Bird c = new Bird();
c->speak();
tweet !
a = c;
a->speak();
tweet !

Merits of Static versus Dynamic Method Binding

Arguments concerning static versus dynamic binding mirror those concerning static versus
dynamic typing.

 Efficiency - static binding uses least CPU cycles, dynamic binding requires more time.
 Error detection - static binding permits errors to be caught at compile time rather
than run-time.
 Flexibility - dynamic binding permits greater flexibility, static binding creates rigidity
and inhibits reuse.

Chapter Summary

 A statically typed language associated types with variables, a dynamically typed


language associates types with values.
 Static typing gives better error detection, better run-time efficiency, less flexibility.
 In a statically typed OO language, an object variable can still hold values from a child
class.
 The static class is the class of the declaration, the dynamic class is the class of the
value currently held.
 The legality of a message is checked using the static class.
 A message can be bound to a method using either the static or dynamic class. Most
languages use the dynamic class. Some languages allow the programmer to choose
which method is used.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 55 of 166


Object-Oriented Programming Concepts and C++ References

Session 10: Generics

Templates
Source http://www.bogotobogo.com/cplusplus/templates.php
Date of
Retrieval: 17/5/2012

We use templates when we need functions/classes that apply the same algorithm to a
several types. So we can use the same function/class regardless of the types of the
argument or result. In other words, a template is a mechanism that allows a programmer
to use types as parameters for a class or a function. The compiler then generates a specific
class or function when we later provide specific types as arguments. Such a function/class is
called a generic function/class, and the ability to use and create generic
functions/classes is one of the key features of C++.

We call a class template a type generator. The process of generating types from a class
template is called specialization or template instantiation.

In most of the cases, template instantiation is very complicated, but that complexity is in
the domain of compiler writer, not the template user. Template instantiation takes place at
compile time or link time, not at run time.

The syntax is:

template <class T> function_declaration;


or
template <typename T> function_declaration;

We can use either of them. They are not different since both expressions have exactly the
same meaning and behave exactly the same way.

Let's take one example of how template generates a code. We have a function like this:

void f(vector<string>&v)
{
v.push_back("Steve Jobs");
}

The compiler, when it sees v.push_back("Steve Jobs"), generates a function something


like this:

void vector<string>::push_back(const string& s){...}

from the following template definition:

templatevoid vector<T>::push_back(const T& s){...}

© Aptech Ltd. Version 1.0 Page 56 of 166


Object-Oriented Programming Concepts and C++ References

Templates are the foundation of generic programming. Generic programming relies on


polymorphism. Though there are several differences between OOP (class hierarchies and
virtual functions) and generic programming (templates), the major difference is:

 Generic (templates): compile time resolution.


The choice of function invoked when we use is determined by the compiler at
compile time.
 OOP (virtual functions): run time resolution.

Generic programming lets us write classes and functions that are polymorphic across
unrelated types at compile time. A single class or function can be used to manipulate
objects of a variety of types. The standard library containers, iterators, and algorithms are
examples of generic programming. We can use library classes and functions on any kind of
type.

When we parameterize a class, we get a class template, and when we parameterize a


function, we get a function template.

So, what do people actually use template for?

 When performance is essential.


 When flexibility in combining information from several types is essential.

But note that, the flexibility and performance come at the cost of poor error diagnostics and
poor error messages.

Terminology of Templates

Let's review the terminology of template using the following example implementing a
generic stack class:

template <typename T>


class Stack
{
public:
void push(T val);
T pop();
bool isEmpty() const;
private:
std:vector<T> mStack;
};

 Template Parameters

These names are listed after the template keyword in a template declarations. As
shown in the example, T is the single template parameter specified in out Stack.

 Template Arguments

© Aptech Ltd. Version 1.0 Page 57 of 166


Object-Oriented Programming Concepts and C++ References

These are substituted for template parameters during specialization. In our example,
given a specialization Stack<int>, the int is a template argument.

 Instantiation

This is when the compiler generates a regular class, method, or function by


substituting each of the template's parameters with a concrete type. This can happen
implicitly when we create an object based on a template or explicitly if we want to
control when the code generation happens. For instance, the following code creates
two specific stack instances and will normally cause the compiler to generate code
for these two different types:

Stack<T> myIntStack;
Stack<T> myStringStack;

 Implicit Instantiation

This is when the compiler decides when to generate code for our template instances.
Leaving the decision to the compiler means that it must find an appropriate place to
insert the code, and it must also make sure that only one instance of the code exists
to avoid duplicate symbol errors. This is non-trivial problem and can cause extra
bloat in our object files or longer compile and line times to solve. Most importantly,
implicit instantiation means that we have to include the template definitions in our
header files so that the compiler has access to the definitions whenever it needs to
generate the instantiation code.

 Emplicit Instantiation

This is when the programmer determine when the compiler should generate the code
for a specific specialization. This can make for much more efficient compilation and
link times because the compiler no longer needs to maintain bookkeeping
information for all of its implicit instantiations. The onus, however, is then placed on
the programmer to ensure that a particular specialization is explicitly instantiated
once and only onece. So, explicit instantiation allows us to move the template
implementation into the .cpp file, and so hide from the user.

 Lazy Instantiation
This describes the standard implicit instantation behavior of a C++ compiler wherein
it will only generate code for the parts of a template that are actually used. Given the
previous two instantiations, for example, if we never called isEmpty() on the
myStringStack object, then the compiler would not generate code for the
std::string specialization of that method. This means that we can instantiate a
template with a type that can be used by some, but not all, methods of a class
template. If one method uses the >= operator, but the type we want to instantiate
does not define this operator. This is fine as long as we don't call the particular
method that attempts to use the >= operator.

© Aptech Ltd. Version 1.0 Page 58 of 166


Object-Oriented Programming Concepts and C++ References

 Specialization

When a template is instantiated, the resulting class, method, or function is called a


specialization. More specifically, this is an instantiated (or generated) specialization.
However, the term specialization can also be used when we provide a custom
implementation for a function by specifying concrete types for all the template
parameters. The following is called an explicit specialization:

tempate<>
void Stack<int>::push(int val)
{
// integer specific push implementation
}

 Partial Specialization

This is when we provide a specialization of the template for a subset of all possible
cases. In other words, we specialize one feature of the template but still allow the
user to specify other features. For example, if our template accepts multiple
parameters, we could partially specialize it by defining a case where we specify a
concrete type for only one of the parameters. In our Stack example with a single
template parameter, we could partially specialize this template to specifically handle
pointers to any type T. This still lets users create a stack of any type, but it also lets
us write specific logic to handle the case where users create a stack of pointers. This
partially specialized class declaration looks like this:

template <typename T>


class Stack<T*>
{
public:
void push(T* val);
T* pop();
bool isEmpty() const;
private:
std:vector<T*> mStack;
};

Pros and Cons of Templates

 Pros
o It provides us type-safe, efficient generic containers and generic algorithms
o The main reason for using C++ and templates is the trade-offs in
performance and maintainability outweigh the bigger size of the resulting
code and longer compile times.
o The drawbacks of not using them are likely to be much greater.
 Cons
o Templates can lead to slower compile-times and possibly larger executable.
o Compilers often produce incomprehensible poor error diagnostics and poor
error messages.

© Aptech Ltd. Version 1.0 Page 59 of 166


Object-Oriented Programming Concepts and C++ References

o The design of the STL collections tends to lead to a lot of copying of objects.
The original smart pointer, std::auto_ptr, wasn't suitable for use in most
collections. Things could be improved if we use TR1 pointers.

Function Templates

Here is a simple example of how we use the template for a function which gives us the
minimum value.

#include <iostream>

template <class T>


const T& min(const T& a, const T& b) {
return a < b ? a : b;
}

int main()
{
int x = 10, y = 20;
long xLong = 100, yLong = 200;
int minimum = min<int>(x, y);
long minimumLong = min<long>(xLong,yLong);
std::cout << "minimum = " << minimum << std::endl;
std::cout << "minimumLong = " << minimumLong << std::endl;
}

A function template can be declared inline in the same way as a nontemplate function.
The specifier is placed following the template parameter list and before the return type.
It shouldn't be placed in front of the template keyword. So, it looks like this:

template <class T>


inline const T& min(const T& a, const T& b) {

But not this:

inline template <class T>


const T& min(const T& a, const T& b) {

We can also define function templates that accept more than one type parameter,
simply by specifying more template parameters between the angle brackets as in the
example below.

template <class T, class U>


inline const T& min(const T& a, const U& b) {
return a < b ? a : b;
}

Class Templates

© Aptech Ltd. Version 1.0 Page 60 of 166


Object-Oriented Programming Concepts and C++ References

Class can be generic using template.

template <class T>


class Complx {
private:
T real, imag;
public:
Complx(T&, T&);
T& getReal();
T& getImag();
};

template <class T>


Complx<T>::Complx(T& a, T& b) {
real = a;
imag = b;
}

template <class T>


T& Complx<T>::getReal() {
return real;
}

template <class T>


T& Complx<T>::getImag() {
return imag;
}

#include <iostream>

int main()
{
double i=100, j=200;
Complx <double> myComplx(i,j);

std::cout <<"My complex is " << myComplx.getReal() << ","


<< myComplx.getImag() << std::endl;
}

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 61 of 166


Object-Oriented Programming Concepts and C++ References

Session 11: Frameworks and Reflection

Struts
Source http://onjava.com/onjava/2005/11/02/what-is-struts.html
Date of
Retrieval: 17/5/2012

Apache Struts is an open source Java framework used for building web applications based
on the servlet and JavaServer Pages (JSP) technologies. It was created in 2000 by Craig R.
McClanahan and has become the de facto standard framework for web applications in Java.

Is it conceivable that anyone in the business of building software hasn't heard of the Struts
framework? From developers that are just starting out in the business to those long in the
tooth, the name "Struts" surely must ring a bell. But if you haven't spent your development
time in the Java world or haven't had the need to build web applications, Struts might only
be a buzzword that you've added to your resume. For the next five to ten minutes, you're
going to be taken on a whirlwind tour of the Struts framework. Get a drink (non-alcoholic,
of course), sit back, and put your feet up, and learn a little about one of the most popular
free frameworks to ever grace the open source community.

The Web Development Landscape: Six Years Ago

This is going to sound like a grandfather preaching to his grandkids about how tough it was
in his day, but prior to 2000, the landscape for developing Java web applications was much
different. Java servlets had been out for just a short time (relatively speaking) and Sun had
recently released JavaServer Pages (JSP) to counter Microsoft's Active Server Pages (ASP)
technology. JSPs caught on like wildfire and before long, many web applications were being
built using JSPs.

Unfortunately, in an effort to get applications quickly out the door and due to a lack of any
best practices in the industry at the time, many JSP applications became a tangled web of
pages as developers crammed as much of the application functionality into the JSP. This
approach to building JSP applications would eventually be called the JSP "Model 1"
architecture and is shown in Figure 1.

© Aptech Ltd. Version 1.0 Page 62 of 166


Object-Oriented Programming Concepts and C++ References

Figure 1. The JSP Model 1 architecture

The Model 1 architecture used the JSPs to handle the HTTP requests, communicate with the
data layer (via JavaBeans), and to render the next page back to the client. For small
applications, this approach isn't so terrible. But for non-trivial applications where there are
many pages or when the functionality is more traditionally application-like, the Model 1
architecture presents many maintenance and upgradeability challenges.

Developers soon realized that the use of JSPs in conjunction with a single controller servlet
could improve this design greatly. The separation of the presentation layer from the
business logic not only serves to keep the JSPs cleaner, but it allows development teams to
utilize each team member's specialized skill.

This new approach to building JSP applications became known as the JSP "Model 2"
architecture. It was patterned after the Model-View-Controller (MVC) design, which
originated from Smalltalk, where it was used to separate the GUI from the business layer.
(When MVC is done on the Web, it is often referred as Web MVC.) The JSP Model 2
architecture is shown in Figure 2.

Figure 2. The JSP Model 2 architecture

The Model 2 architecture uses a Java servlet to receive the HTTP requests from the browser
and to communicate with the model layer. The JSPs are used only for presentation. The

© Aptech Ltd. Version 1.0 Page 63 of 166


Object-Oriented Programming Concepts and C++ References

same controller that receives the request is responsible for determining which view gets
returned back to the client.

Along Comes Jakarta Struts

Three things started to happen around 2000 that helped catapult Struts into the forefront of
web development frameworks. First, the open source community was starting to gain
momentum and popularity. Open source projects like Tomcat, Ant, and Log4J were gaining
mindshare with the development community, and managers were just starting accept that
free software had a place in the business world.

The second thing that was happening around the same time was a huge number of new
startup companies (affectionately called dot coms) were trying out their various business
models on the populace. Most of these business models involved some form of web
presence and therefore required a web framework. (In retrospect, for those of us who lived
through it, these times were very stressful and exciting at the same time.)

It was also during this time that Craig McClanahan created the open source web
development framework called Struts, which was based on the Model 2 architecture and
which was added to the list of Jakarta projects. Little did he probably know that the planets
were lining up behind his newly created web framework?

Benefits of the Struts Framework

There are literally hundreds of web development frameworks available, each sharing some
similarities while providing their own twist on what a web framework should be. Many of
these frameworks have been around several years and have positives and negatives
associated with them. While the Struts framework is not completely unique, it provides
some key benefits:

 Based on a Model 2 MVC implementation.


 Supports Java's "Write Once, Run Anywhere" philosophy.
 Supports different model implementations (JavaBeans, EJB, etc.).
 Support for internationalization (I18N).
 Includes a rich set of JSP tag libraries.
 Contains many extension points for customization.
 Supports different presentation implementations (JSP, XML/XSLT, JavaServer Faces).

Is Struts right for your project? (Manager version)

 Developed by industry experts


 Stable and mature
 Manageable learning curve
 Open source (No cost)
 Large user community (several thousand)
 30,000 downloads per month
 It's probably similar to what you would build if not using Struts
 Good documentation; many books, articles, and resources available

Is Struts right for your team? (Developer version)

© Aptech Ltd. Version 1.0 Page 64 of 166


Object-Oriented Programming Concepts and C++ References

 Feature-rich
 Free to develop and deploy
 Many supported third-party tools
 Flexible and extendable
 J2EE technologies
 Expert developers and committers
 Large user community
 Performant

Whether you're a manager being pushed by your development team to allow Struts into
your organization or a developer wondering if all of the hype is true, these two lists should
tell you that Struts is a serious framework.

Overview of the Struts Framework

The Struts framework is composed of approximately 300 classes and interfaces organized in
about 12 top-level packages. Besides the utility and helper classes, much of the framework
consists of classes and interfaces for working with either the controller functionality or the
presentation through custom tag libraries. The choice of a model layer is a decision that's
left up to you. Some argue that this is a deficiency in the framework, while seasoned Struts
developers would say that this freedom is warranted and welcomed. A high-level view of the
Struts architecture is shown in Figure 3.

Figure 3. The Struts architecture

The Struts Controller Components

When a request is sent to a Struts application, it's handled by the Struts ActionServlet. The
Struts framework includes a concrete ActionServlet that for many users is adequate and
requires no customization or additional work.

When the ActionServlet receives a request, it inspects the URL and based on the Struts
configuration files, it delegates the handling of the request to an Action class. As you can
see from Figure 3, the Action class is part of the controller and is responsible for
communicating with the model layer. The Struts framework provides an abstract Action
class that you must extend for your own needs.

© Aptech Ltd. Version 1.0 Page 65 of 166


Object-Oriented Programming Concepts and C++ References

Example 1 shows you an example of an Action class from the Beer4All Struts application
that extends the base Action class.

Example 1. The Beer4All LoginAction class is called by the ActionServlet when users attempt
to log in to the site.

public class LoginAction extends Action {


/**
* Called by the ActionServlet when the a user attempts to login.
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {

/*
* Get the user's login name and password. They should have been
* validated by the ActionForm.
*/
String username = ((LoginForm) form).getUsername();
String password = ((LoginForm) form).getPassword();

// Login through the security service


Beer4AllService serviceImpl = this.getBeer4AllService();

// Authenticate the user with the backend


UserView userView = serviceImpl.authenticate(username, password);

// Invalide the current session and create a new one


HttpSession session = request.getSession(false);
session.invalidate();
session = request.getSession(true);

// Store the user object into the session


session.setAttribute("USER", userView);

return mapping.findForward("success");
}
}

The Action class in Example 1 is called when a user attempts to log in to the Beer4All
website, probably to order their next shipment of ale. The URL that the browser would have
sent to the ActionServlet would have looked something like http://beer4all.com/login.do.
When the ActionServlet gets this request, it consults its mapping (which was loaded from
the Struts configuration files at startup) and discovers that the LoginAction is the Action
class that handles the login.do request. The ActionServlet then calls the Action's execute()
method to perform whatever task the Action class was meant to perform. Within the
execute() method, you can put in whatever logic you need in order to fulfill the request. For
example, you could acquire a Hibernate session and query the database, invoke a Stateless
Session Bean (SLSB) or maybe use JavaMail to send an email to a registered user, just to
name a few.

© Aptech Ltd. Version 1.0 Page 66 of 166


Object-Oriented Programming Concepts and C++ References

The LoginAction from Example 1 authenticates the user through some service (the details of
which are not shown), presumably to a database. When the Action class is finished
performing its logic, it typically stores objects (JavaBeans) into the request, session, or
even application scope, and informs the controller servlet whether it was successful or not.
Based on the mappings for the LoginAction class, the ActionServlet will determine the next
page the user should be shown. Because the JSP has access to the same request, session,
or application scope, it can access those stored objects and use them to render the view for
the client.

The Struts framework includes several pre-built Actions that make it easier to build out
functionality. You don't always have to map a web request to a separate Action class. The
org.apache.struts.actions.DispatchAction, for example, is designed to support multiple
requests. In the Beer4All application, we have the typical e-commerce shopping cart
functionality (view the cart, add items, checkout, etc.). Instead of creating separate Action
classes for each action, we can use the DispatchAction to contain all of the methods that
work on the user's cart. Using the DispatchAction class keeps the number of Action classes
to a minimum, which helps to simplify the maintenance of the application.

Choosing a Model Layer for Struts

As we said earlier, the Struts framework doesn't provide much in the way of the model, but
it can integrate with any current model approach, including JDBC and EJB, as well as third-
party packages like Hibernate, iBATIS, and Object Relational Bridge. One of the most
important best practices for the Struts framework is that business logic should stay out of
the Action class, regardless of what you're using for the Model layer. Putting business logic
in the Action classes hurts reusability of the Action class and couples the framework too
tightly with the business tier. Instead, the Action classes should utilize a service layer, even
when using straight JDBC. Back in Example 1, for example, the authenticate() method was
called on a service called Beer4AllService. This might have been a Stateless Session Bean, a
RMI object, or maybe just a simple Java class that wraps JDBC code. The good news is that
you're not limited with Struts.

The Struts Presentation Layer

The Struts presentation layer is almost as flexible as the model layer. You can (and most
users do) use JavaServer Pages, of course. But you can also use one of many alternative
presentation technologies if JSP isn't your thing. From Velocity Templates to XSLT to
JavaServer Faces, Struts easily integrates with many.

If you are using JSP, then you're in luck, because Struts has a fairly exhaustive set of JSP
custom tags.

The Venerable Struts Tag Library

The support for custom tags was added to the JSP language to allow developers to extend
the JSP library. The Struts framework includes over 60 JSP custom tags grouped into one of
the five libraries shown in Table 1.

Table 1. Struts includes many custom tags that many building JSP applications easier.

Tag Library Purpose

© Aptech Ltd. Version 1.0 Page 67 of 166


Object-Oriented Programming Concepts and C++ References

HTML Tag Contains tags used to create Struts input forms, as well as other tags
Library generally useful in the creation of HTML-based user interfaces.
Bean Tag Contains tags useful for accessing beans and their properties, as well as
Library defining new beans.
Contains tags that are useful in managing conditional generation of output
Logic Tag
text, looping over object collections for repetitive generation of output text,
Library
and application flow management.
Nested Tag
Contains tags useful for dealing with object graphs and nested properties.
Library
Tiles builds on the "include" feature provided by the JavaServer Pages
Tiles Tag
specification to provide a full-featured, robust framework for assembling
Library
presentation pages from component parts.

The Struts framework also works quite nicely with the JSP Standard Tag Library (JSTL),
which was created to provide a set of standard tags that will work in all compliant JSP
containers.

Presentation Validation

Another great feature of Struts is the presentation validation that's included with the
Commons Validator. The Validator framework was created by David Winterfeldt and
integrated into Struts in version 1.1. The Validator provides for presentation validation (and
with some customization, business validation) by declaring the rules in an external XML file.
The framework comes with many pre-built validation rules, like checking for required fields,
max and min lengths, and date validations. It also supports regular expressions. You can
even create you own validation rules and easily add them to your application.

Struts' Other Great Features

We're running out of time. I promised you that it wouldn't take longer than five or ten
minutes to read this and unfortunately, there are many other areas of Struts that deserve
the same amount of attention. Just look at the following list of features that we haven't
even talked about yet:

 Support for modules


 Declarative exception-handling
 Dynamic ActionForms
 New config package
 Tiles
 Plugins

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 68 of 166


Object-Oriented Programming Concepts and C++ References

Session 12: Patterns

Design Patterns
Source http://www.oodesign.com/
Date of
Retrieval: 17/5/2012

Creational Design Patterns:

Singleton - Ensure that only one instance of a class is created and Provide a global
access point to the object.

Factory(Simplified version of Factory Method) - Creates objects without exposing the


instantiation logic to the client and Refers to the newly created object through a
common interface.

© Aptech Ltd. Version 1.0 Page 69 of 166


Object-Oriented Programming Concepts and C++ References

Builder - Defines an instance for creating an object but letting subclasses decide which class to
instantiate and Allows a finer control over the construction process.

Prototype - Specify the kinds of objects to create using a prototypical instance, and create new
objects by copying this prototype.

© Aptech Ltd. Version 1.0 Page 70 of 166


Object-Oriented Programming Concepts and C++ References

Behavioral Design Patterns:

Chain of Responsibiliy - It avoids attaching the sender of a request to its receiver, giving this
way other objects the possibility of handling the request too.
- The objects become parts of a chain and the request is sent from one object to another across
the chain until one of the objects will handle it.

Command - Encapsulate a request in an object, Allows the parameterization of clients with


different requests and Allows saving the requests in a queue.

© Aptech Ltd. Version 1.0 Page 71 of 166


Object-Oriented Programming Concepts and C++ References

Interpreter - Given a language, define a representation for its grammar along with an
interpreter that uses the representation to interpret sentences in the language / Map a domain to
a language, the language to a grammar, and the grammar to a hierarchical object-oriented
design

Iterator - Provide a way to access the elements of an aggregate object sequentially without
exposing its underlying representation.

© Aptech Ltd. Version 1.0 Page 72 of 166


Object-Oriented Programming Concepts and C++ References

Mediator - Define an object that encapsulates how a set of objects interact. Mediator promotes
loose coupling by keeping objects from referring to each other explicitly, and it lets you vary
their interaction independently.

© Aptech Ltd. Version 1.0 Page 73 of 166


Object-Oriented Programming Concepts and C++ References

Observer - Define a one-to-many dependency between objects so that when one object
changes state, all its dependents are notified and updated automatically.

Strategy - Define a family of algorithms, encapsulate each one, and make them
interchangeable. Strategy lets the algorithm vary independently from clients that use it.

© Aptech Ltd. Version 1.0 Page 74 of 166


Object-Oriented Programming Concepts and C++ References

Visitor - Represents an operation to be performed on the elements of an object structure /


Visitor lets you define a new operation without changing the classes of the elements on which it
operates.

Structural Design Patterns:

Adapter - Convert the interface of a class into another interface clients expect. / Adapter lets
classes work together, that could not otherwise because of incompatible interfaces.

© Aptech Ltd. Version 1.0 Page 75 of 166


Object-Oriented Programming Concepts and C++ References

Bridge - Compose objects into tree structures to represent part-whole hierarchies. / Composite
lets clients treat individual objects and compositions of objects uniformly.

Composite - Compose objects into tree structures to represent part-whole hierarchies. /


Composite lets clients treat individual objects and compositions of objects uniformly.

© Aptech Ltd. Version 1.0 Page 76 of 166


Object-Oriented Programming Concepts and C++ References

Decorator - add additional responsibilities dynamically to an object.

Flyweight - use sharing to support a large number of objects that have part of their internal
state in common where the other part of state can vary.

© Aptech Ltd. Version 1.0 Page 77 of 166


Object-Oriented Programming Concepts and C++ References

Proxy - provide a “Placeholder” for an object to control references to it.

~~~ End of Article ~~~

~~End of References for Object-Oriented Programming Concepts~~

© Aptech Ltd. Version 1.0 Page 78 of 166


Object-Oriented Programming with C++
Object-Oriented Programming Concepts and C++ References

Table of Contents

S. No. Sessions Page numbers


1. Session 1: Object Oriented Concepts and C++
• Basic Object-Oriented Concepts 81
• Procedural oriented programming 92
2. Session 2: Basics of C++
93
• Basic Concepts
101
• The basics of C++
3. Session 3: Flow control statements
106
• Decisions, Decisions: Making Choices in C++

4. Session 4: Functions, Pointers, and Arrays


114
• Functions
117
• Pointers in C++
5. Session 5: Function Overloading
120
• C++ function overloading programs
123
• C++ Operator Overloading Guidelines
6. Session 6: Inheritance
• Inheritance (object-oriented programming) 129
• Introduction to Inheritance in C++ 135
7. Session 7: Multiple Inheritance and Polymorphism
145
• Introduction to Polymorphism in C++
153
• Polymorphism
8. Session 8: Data Structures using C++ and Exception
Handling
• Try and Catch 160
• Error and Exception Handling 164

© Aptech Ltd. Version 1.0 Page 80 of 166


Object-Oriented Programming Concepts and C++ References

Session 1: Object Oriented Concepts and C++

Basic Object-Oriented Concepts


Source http://www.ipipan.gda.pl/~marek/objects/TOA/oobasics/oobasics.html
Date of 14/05/2015
Retrieval

How People Understand Technology

There is an old story of how several blind men set out to understand what an elephant was by examining
a live specimen. Each of them explored a different part of the elephant's body. One blind man, falling
against the elephant's side, proclaimed that an elephant must be very much like a wall. Another, grasping
the elephant's ear, decided that an elephant must closely resemble a leaf. One grabbed the elephant's tail
and determined that elephants must resemble ropes. Yet another felt the elephant's leg and came away
convinced that elephants are very much like trees. Still another held the elephant's trunk and exclaimed
that elephants had much in common with snakes.

While there was at least a grain of truth in each blind man's observation, none of them had a complete
and accurate understanding of just what an elephant is. We can imagine the many animated debates that
these blind men had when they compared notes -- each sure that the others must be wrong.

Often, people studying technology are like the blind men in our story. It is very common to focus intently
on one facet of one aspect of a technology while ignoring the vast breadth of the same technology. There
is nothing wrong with this -- unless a person studying the facet begins to think that he or she has
somehow acquired a good grasp of the entire technology.

To acquire an in-depth understanding of a technology requires a great deal of research. The sheer bulk of
material that must be examined is daunting. The task is further complicated by the unfortunate errors
contained in many discussions. Even if an individual can assimilate a large quantity of material and easily
identify any errors, there is still the process of analyzing what has been assimilated. To truly understand a
technology, an individual must be able to recognize valid patterns, and to easily spot invalid patterns.

How People Approach Object-Oriented Technology

Object-oriented technology is both immense and far-reaching. End users of computer systems and
computer-based systems notice the effects of object-oriented technology in the form of increasingly easy-
to-use software applications and operating systems and in more flexible services being provided by such
industries as banking, telecommunications, and cable television. For the software engineer, object-
oriented technology encompasses object-oriented programming languages, object-oriented development

© Aptech Ltd. Version 1.0 Page 81 of 166


Object-Oriented Programming Concepts and C++ References

methodologies, management of object-oriented projects, object-oriented computer hardware, and object-


oriented computer aided software engineering, among others.

It is not surprising, therefore, that there is some confusion regarding object-oriented terms and concepts.
In this article, we will provide the reader with working definitions for object-oriented terms and concepts
that are necessary for a reader to acquire a basic understanding of object-oriented technology.

Many of the terms commonly used in object-oriented technology were originally used to describe object-
oriented programming (coding) concepts. Specifically, although the terms were borrowed from a non-
computer-software perspective, they were first used extensively to describe concepts embodied in object-
oriented programming languages, such as Smalltalk, C++, and Eiffel. However, these terms are quite
useful even if one never intends to write any software at all.

For example, an industrial modeler could create an object-oriented model of a plastics manufacturing
facility. Molding machines, plastic parts, and even the "recipes" (proportional combinations) of the
chemicals used to create the various plastics could all be described in object-oriented terms. Further,
dynamic and static relationships among these items could also be described in object-oriented terms.

Finally, keep in mind that there is no one ultimate set of definitions for object-oriented terms and
concepts. Depending on who you are talking to, terms and definitions will vary slightly. This is normal; in
different parts of the United States, the same breakfast item might be referred to as a pancake, a griddle
cake, a flapjack, or a hot cake. Even in technical arenas, this variation in terminology is common. A
chemist might use the terms "valance" and "oxidation state" to identify the same concept.

Object-Oriented Terms and Concepts

Objects

Objects are the physical and conceptual things we find in the universe around us. Hardware, software,
documents, human beings, and even concepts are all examples of objects. For purposes of modeling his
or her company, a chief executive officer could view employees, buildings, divisions, documents, and
benefits packages as objects. An automotive engineer would see tires, doors, engines, top speed, and
the current fuel level as objects. Atoms, molecules, volumes, and temperatures would all be objects a
chemist might consider in creating an object-oriented simulation of a chemical reaction. Finally, a software
engineer would consider stacks, queues, windows, and check boxes as objects.

Objects are thought of as having state. The state of an object is the condition of the object, or a set of
circumstances describing the object. It is not uncommon to hear people talk about the "state information"
associated with a particular object. For example, the state of a bank account object would include the
current balance, the state of a clock object would be the current time, the state of an electric light bulb
would be "on" or "off." For complex objects like a human being or an automobile, a complete description
of the state might be very complex. Fortunately, when we use objects to model real world or imagined
situations, we typically restrict the possible states of the objects to only those that are relevant to our
models.

We also think of the state of an object as something that is internal to an object. For example, if we place
a message in a mailbox, the (internal) state of the mailbox object is changed, whereas the (internal) state
of the message object remains unchanged.

Sometimes people think of objects as being strictly static. That is, the state of an object will not change
unless something outside of the object requests the object to change its state. Indeed, many objects are
passive (static). A list of names does not spontaneously add new names to itself, nor would we expect it
to spontaneously delete names from itself.

© Aptech Ltd. Version 1.0 Page 82 of 166


Object-Oriented Programming Concepts and C++ References

However, it is possible for some objects to change their own state. If an object is capable of
spontaneously changing its own state, we refer to it as an "object with life." (Objects with life are
sometimes also called "active objects" or "actors.") Clocks and timers are common examples of objects
with life. If we were modeling a business process, we would recognize that salespeople and customers
were also objects with life.

Classes, Metaclasses, Parameterized Classes, and Exemplars

There are two broad categories of objects: classes and instances. Users of object-oriented technology
usually think of classes as containing the information necessary to create instances, i.e., the structure and
capabilities of an instance is determined by its corresponding class. There are three commonly used (and
different) views on the definition for "class":

• A class is a pattern, template, or blueprint for a


category of structurally identical items. The items
created using the class are called instances. This
is often referred to as the "class as a `cookie
cutter'" view. As you might guess, the instances
are the "cookies."
• A class is a thing that consists of both a pattern
and a mechanism for creating items based on that
pattern. This is the "class as an `instance factory'"
view; instances are the individual items that are
"manufactured" (created) using the class's
creation mechanism.
• A class is the set of all items created using a
specific pattern. Said another way, the class is the
set of all instances of that pattern.

In this article, we will use the definition of a "class an `instance factory.'"

We should note that it is possible for an instance of a class to also be a class. A metaclass is a class
whose instances themselves are classes. This means when we use the instance creation mechanism in a
metaclass, the instance created will itself be a class. The instance creation mechanism of this class can,
in turn, be used to create instances -- although these instances may or may not themselves be classes.

A concept very similar to the metaclass is the parameterized class. A parameterized class is a template
for a class wherein specific items have been identified as being required to create non-parameterized
classes based on the template. In effect, a parameterized class can be viewed as a "fill in the blanks"
version of a class. One cannot directly use the instance creation mechanism of a parameterized class.
First, we must supply the required parameters, resulting in the creation of a non-parameterized class.
Once we have a non-parameterized class, we can use its creation mechanisms to create instances.

In this article, we will use the term "class" to mean metaclass, parameterized class, or a class that is
neither a metaclass nor a parameterized class. We will make a distinction only when it is necessary to do
so. Further, we will occasionally refer to "non-class instances." A non-class instance is an instance of a

© Aptech Ltd. Version 1.0 Page 83 of 166


Object-Oriented Programming Concepts and C++ References

class, but is itself not a class. An instance of a metaclass, for example, would not be a non-class
instance.

In this article, we will sometimes refer to "instantiation." Instantiation has two common meanings:

• as a verb, instantiation is the process of creating an instance of a class, and


• as a noun, an instantiation is an instance of a class.

Some people restrict the use of the term "object" to instances of classes. For these people, classes are
not objects. However, when these people are confronted with the concepts of metaclasses and
parameterized classes, they have a difficulty attempting to resolve the "problems" these concepts
introduce. For example, is a class that is an instance of a metaclass an object -- even though it is itself a
class? In this article, we will use the term "object" to refer to both classes and their instances. We will only
distinguish between the two when needed.

Black Boxes and Interfaces


Objects are "black boxes." Specifically, the underlying implementations of objects are hidden from those
that use the object. In object-oriented systems, it is only the producer (creator, designer, or builder) of an
object that knows the details about the internal construction of that object. The consumers (users) of an
object are denied knowledge of the inner workings of the object, and must deal with an object via one of
its three distinct interfaces:

• The "public" interface. This is the interface that is open (visible) to everybody.
• The "inheritance" interface. This is the interface that is accessible only by direct specializations of
the object. (We will discuss inheritance and specialization later in this chapter.) In class-based
object-oriented systems, only classes can provide an inheritance interface.
• The "parameter" interface. In the case of parameterized classes, the parameter interface defines
the parameters that must be supplied to create an instance of the parameterized class.

Another way of saying that an item is in the public interface of an object is to say that the object "exports"
that item. Similarly, when an object requires information from outside of itself (e.g., as with the parameters
in a parameterized class), we can say that the object needs to "import" that information.

Aggregation

It is, of course, possible for objects to be composed of other objects. Aggregation is either:

• The process of creating a new object from two or more other objects, or
• An object that is composed of two or more other objects.

For example, a date object could be fashioned from a month object, a day object, and a year object. A list
of names object, for example, can be thought of as containing many name objects.

A monolithic object is an object that has no externally-discernible structure. Said another way, a
monolithic object does not appear to have been constructed from two or more other objects. Specifically,
a monolithic object can only be treated as a cohesive whole. Those outside of a monolithic object cannot
directly interact with any (real or imagined) objects within the monolithic object. A radio button in a
graphical user interface (GUI) is an example of a monolithic object.

© Aptech Ltd. Version 1.0 Page 84 of 166


Object-Oriented Programming Concepts and C++ References

Composite objects are objects that have an externally-discernible structure, and the structure can be
addressed via the public interface of the composite object. The objects that comprise a composite object
are referred to as component objects. Composite objects meet one or both of the following criteria:

• The state of a composite object is directly affected by the presence or absence of one or more of
its component objects, and/or
• The component objects can be directly referenced via the public interface of their corresponding
composite object.

It is useful to divide composite objects into two subcategories: heterogeneous composite objects and
homogeneous composite objects:

• A heterogeneous composite object is a composite object that is conceptually composed of


component objects that are not all conceptually the same. For example, a date (made up of a
month object, a day object, and a year object) is a heterogeneous composite object.
• A homogeneous composite object is a composite object that is conceptually composed of
component objects that are all conceptually the same. For example, a list of addresses is a
homogeneous composite object.

The rules for designing heterogeneous composite objects are different from the rules for designing
homogeneous composite objects.

Specialization and Inheritance

Aggregation is not the only way in which two objects can be related. One object can be a specialization of
another object. Specialization is either:

• The process of defining a new object based on a (typically) more narrow definition of an existing
object, or
• An object that is directly related to, and more narrowly defined than, another object.

Specialization is usually associated with classes. It is usually only in the so-called "classless" object-
oriented systems that we think of specialization for objects other than classes.

Depending on their technical background, there are a number of different ways in which people express
specialization. For example, those who are familiar with an object-oriented programming language called
Smalltalk refer to specializations as "subclasses" and to the corresponding generalizations of these
specializations as "superclasses." Those with a background in the C++ programming language use the
term "derived class" for specialization and "base class" for corresponding generalizations.

It is common to say that everything that is true for a generalization is also true for its corresponding
specialization. We can, for example, define "checking accounts" and "savings accounts" as
specializations of "bank accounts." Another way of saying this is that a checking account is a kind of bank
account, and a savings account is a kind of bank account. Still another way of expressing this idea is to
say that everything that was true for the bank account is also true for the savings account and the
checking account.

In an object-oriented context, we speak of specializations as "inheriting" characteristics from their


corresponding generalizations. Inheritance can be defined as the process whereby one object acquires
(gets, receives) characteristics from one or more other objects. Some object-oriented systems permit only
single inheritance, a situation in which a specialization may only acquire characteristics from a single
generalization. Many object-oriented systems, however, allow for multiple inheritance, a situation in
which a specialization may acquire characteristics from two or more corresponding generalizations.

© Aptech Ltd. Version 1.0 Page 85 of 166


Object-Oriented Programming Concepts and C++ References

Our previous discussion of the bank account, checking


account, and savings account was an example of single
inheritance. A telescope and a television set are both
specializations of "device that enables one to see things far
away." A television set is also a kind of "electronic device."
You might say that a television set acquires characteristics
from two different generalizations, "device that enables one
to see things far away" and "electronic device." Therefore,
a television set is a product of multiple inheritance.

Abstract Classes

We usually think of classes as being complete definitions. However, there are situations where
incomplete definitions are useful, and classes that represent these incomplete definitions are equally
useful. For example, in everyday conversation, we might talk about such items as bank accounts,
insurance policies, and houses. In object-oriented thinking, we often isolate useful, but incomplete,
concepts such as these into their own special classes.

Abstract classes are classes that embody coherent and cohesive, but incomplete, concepts, and in turn,
make these characteristics available to their specializations via inheritance. People sometimes use the
terms "partial type" and "abstract superclass" as synonyms for abstract class. While we would never
create instances of abstract classes, we most certainly would make their individual characteristics
available to more specialized classes via inheritance.

For example, consider the concept of an automobile. On one hand, most people know what an
automobile is. On the other hand, "automobile" is not a complete definition for any vehicle. It would be
quite accurate to describe "automobile" as the set of characteristics that make a thing an automobile, in
other words, the "essence of automobile-ness."

Operations

The public interface of an object typically contains three different categories of items:

• Operations (sometimes referred to as "method selectors," "method interfaces," "messages," or


"methods"),
• Constants, and
• Exceptions.

An operation in the public interface of an object advertises a functional capability of that object. For
example, "deposit" would be an operation in the public interface of a bank account object, "what is current
temperature" would be an operation in the public interface of a temperature sensor object, and
"increment" would be an operation in the public interface of a counter object.

The actual algorithm for accomplishing an operation is referred to as a method. Unlike operations,
methods are not in the public interface for an object. Rather, methods are hidden on the inside of an
object. So, while users of bank account objects would know that they could make a deposit into a bank

© Aptech Ltd. Version 1.0 Page 86 of 166


Object-Oriented Programming Concepts and C++ References

account, they would be unaware of the details as to how that deposit actually got credited to the bank
account.

We refer to the operations in the public interface of an object as "suffered operations." Suffered
operations are operations that meet two criteria: they are things that happen to an object, and they are in
the public interface of that object. For example, we can say that a bank account "suffers" the operation of
having a deposit made into it. The bank account can also "suffer" the operation of being queried as to its
current balance. Some people also refer to suffered operations as "exported operations."

There are three broad categories of suffered operations, i.e.:

• A selector is an operation that tells us something about the state of an object, but cannot by
definition, change the state of the object. An operation that tells us the current balance of a bank
account is an example of a selector operation.
• A constructor is an operation that has the ability to change the state of an object. For example,
an operation in the public interface to a mailbox object that added a message to the mailbox
would be a constructor operation. (Please note that some people restrict the definition of the term
"constructor" to those operations that cause instances of a class to come into existence.)
• In the context of a homogeneous composite object, an iterator is an operation that allows its
users to visit (access) each of the component objects that make up the homogeneous composite
object. If we have a list of addresses, for example, and we wish to print the entire list, an iterator
would allow us to visit each address object within the list and then, in turn, to print each address.

Iterators can be further divided into two broad categories: active (open) iterators and passive (closed)
iterators. Active iterators are objects in their own right. Passive iterators are implemented as operations in
the interface of the object over which they allow iteration. Passive iterators are further broken down into
selective iterators and constructive iterators. Passive selective iterators do not allow their users to change
the object over which the iteration takes place. Passive constructive iterators do allow users to change
the object over which iteration takes place.

We can also describe suffered operations as primitive or composite. A primitive operation is an


operation that cannot be accomplished simply, efficiently, and reliably without direct knowledge of the
underlying (hidden) implementation of the object. As an example, we could argue that an operation that
added an item to a list object, or an operation that deleted an item from a list object were primitive
operations with respect to the list object.

Suppose that we wanted to create a "swap operation”, an operation that would swap in a new item in a
list, while at the same time swapping out an old item in the same list. This is not a primitive operation
since we can accomplish this with a simple combination of the delete operation (deleting the old item)
followed by the add operation (adding the new item). The swap operation is an example of a composite
operation. A composite operation is any operation that is composed, or can be composed, of two or
more primitive operations.

Sometimes objects need help in maintaining their characteristics. Suppose, for example, that we wanted
to create a "generic ordered list" object. An ordered list is a list that must order its contents from the
smallest to the largest. Specifically, every time we add an item to our ordered list, that item would have to
be placed in its proper position with respect to all the other items already in the list. By "generic," we
mean a template that can be instantiated with the category (class) of items we wish to place in the
ordered list.

It would not be unreasonable to implement this object as a parameterized class. Obviously, one of the
parameters would be the category of items (e.g., class) that we desired to place in the list. For example,
could instantiate (make an instance) the generic ordered list with a "name class" resulting in the creation
of an "ordered list of names class."

© Aptech Ltd. Version 1.0 Page 87 of 166


Object-Oriented Programming Concepts and C++ References

There is a problem, however. Given that we could instantiate the generic ordered list with just about any
category of items, how can we be sure that the ordered lists will know how to properly maintain order -- no
matter what we use to instantiate the generic ordered list? Suppose, for example, that we wanted an
ordered list of "fazoomas." How could the generic list class tell if one fazooma was greater than or less
than another fazooma?

A solution would be for the generic ordered list to require a second parameter, a parameter over and
above the category of items (class) that we desired to place in the list. This second parameter would be a
"<" (less than) operation that worked with the category of items to be placed in the list. In the case of our
ordered list of fazoomas, this second parameter would be a "<" that works with fazoomas.

The "<" that worked with fazoomas is an example of a required operation. A required operation is an
operation that an object needs to maintain its outwardly observable characteristics, but which the object
cannot supply itself. Some people refer to required operations as "imported operations".

Constants

In addition to suffered operations, the public interface of an object can also contain constants. Constants
are objects of constant state. Imagine that we want to create a "bounded list of addresses class”. A
bounded list is a list that has a fixed maximum number of elements. A bounded list can be empty, and it
can contain fewer than the maximum number of elements. It can even contain the maximum number of
elements, but it can never contain more than the defined maximum number of elements.

Assume that we place a constant in the public interface of our bounded list of addresses. This constant
represents the maximum number of elements that can be placed in the bounded list. Assume also that
there is a suffered operation that will tell us how many elements (addresses, in our example) are currently
in the bounded list. We can now determine how much room is available in the bounded list by inquiring
how many addresses are already in the list, and then subtracting this from the previously-defined
constant.

In some cases, as with the bounded list example above, constants are provided more for convenience
than necessity. In other cases, such as in the case of encryption algorithms needing a "seed value”,
constants are an absolute requirement.

Exceptions

A third category of items that can be found in the public interface of objects is exceptions. Exceptions
have two different definitions:

• An event that causes suspension of normal application execution, and


• A set of information directly relating to the event that caused suspension of normal application
execution.

Exceptions can be contrasted with an older, less reliable technology: "error codes”. The idea behind error
codes was fairly simple. You would request that an application, or part of an application, accomplish
some work. One of the pieces of information that would be returned to the requester would be an error
code. If all had gone well, the error code would typically have a value of zero. If any problems had
occurred, the error code would have a non-zero value. It was also quite common to associate different
non-zero values of an error code with specific errors.

Error codes suffered from two major problems:

• No one was forced to actually check the value of returned error codes.

© Aptech Ltd. Version 1.0 Page 88 of 166


Object-Oriented Programming Concepts and C++ References

• Changes (additions, deletions, and modifications) in the meanings of the special values assigned
to error codes were not automatically passed on to interested parties. Tracking the effects of a
changed error code value often consumed a significant amount of resources.

To understand how exceptions directly address both of these issues, we first need to understand how
exceptions typically work:

• Exceptions may be defined by the environment or by the user.


• When an exceptional (but not unforeseen) condition occurs, an appropriate exception is
activated. (People use different terms to express the activation of an exception. The most
common is "raise”. Less commonly, people use the terms "throw" or "activate.") This activation
may be automatic (controlled by the environment) or may be expressly requested by the designer
of the object or application.

Examples of exceptional conditions include trying to remove something from an empty container,
directing an elevator on the top floor to "go up”, and attempting to cause a date to take on an invalid value
like "February 31, 1993”.

• Once the exception is activated, normal application execution stops and control is transferred to a
locally defined exception handler, if one is present. If no locally defined exception handler is
present or if the exception handler is not equipped to handle the exception, the exception is
propagated to the next higher level of the application. Exceptions cannot be ignored. An
exception will continue to be sent to higher levels of the application until it is either turned off or
the application ceases to function.
• An exception handler checks to see what type of exception has been activated. If the exception is
one that the handler recognizes, a specific set of actions is taken. Executing a set of actions in
response to an exception is known as "handling the exception." Handling an exception
deactivates the exception; the exception will not be propagated any further.

Unlike error codes, exceptions cannot be ignored. Once an exception has been activated, it demands
attention. In object-oriented systems, exceptions are placed in the public interfaces of objects. Changes in
the public interfaces of objects very often require an automatic rechecking of all other objects that invoke
operations in the changed objects. Thus, changes in exceptions result in at least a partially automated
propagation of change information.

Object Coupling and Object Cohesion

Engineers have known for centuries that the less any one part of a system knows about any other part of
that same system, the better the overall system. Systems whose components are highly independent of
each other are easier to fix and enhance than systems where there are strong interdependencies among
some or all of the components. Highly independent system components are possible when there is
minimal coupling among the components, and each component is highly cohesive.

© Aptech Ltd. Version 1.0 Page 89 of 166


Object-Oriented Programming Concepts and C++ References

Coupling is a measure of the strength of the connection


between any two system components. The more any one
component knows about another component, the tighter
(worse) the coupling is between those two components.
Cohesion is a measure of how logically related the parts of
an individual component are to each other, and to the overall
component. The more logically related the parts of a
component are to each other the higher (better) the cohesion
of that component.

The objects that make up an object-oriented system exhibit object coupling and object cohesion. Object
coupling describes the degree of interrelationships among the objects that make up a system. The more
any one object knows about any other object in the system, the tighter (worse) the coupling is between
those two objects.

To construct systems from objects, we must couple (to some degree) the objects that comprise the
system. This is necessary object coupling. However, if in the design of an individual object, we give that
object direct knowledge of other specific objects, we are unnecessarily coupling the objects. Unnecessary
object coupling reduces both the reusability of individual objects, and the reliability of the systems that
contain unnecessarily coupled objects.

Object cohesion, on the other hand, is a measure of how logically


related the components of the external view of an object are to each
other. For example, if we are told that a date object is comprised of
a month object, a day object, a year object, and the color blue, we
should recognize that the color blue is not appropriate, and lowers
the cohesion of the date object. We want our objects to be as
cohesive as possible for two reasons. First, objects with low
cohesion are more likely to be changed, and are more likely to have
undesirable side effects when they are changed. Second, objects
with low cohesion are seldom easily reusable.

Systems of Objects

In constructing object-oriented models and object-oriented applications, one quickly finds that single
classes and single instances are not enough. You need some way of creating and dealing with large
objects. A system of objects is defined as two or more interacting or interrelated, non-nested objects.
(We exclude simple aggregations of composite objects from our definition of systems of objects.)

Systems of objects fall into two general categories:

© Aptech Ltd. Version 1.0 Page 90 of 166


Object-Oriented Programming Concepts and C++ References

• Kits, which are collections of items (classes, metaclasses, parameterized classes, non-class
instances, other kits, and/or systems of interacting objects) all of which support a single, large,
coherent, object-oriented concept, such as computer graphics windows or insurance policies.
There may indeed be some physical connection among some of the members of a given kit.
However, kits are "granular." While all the components of a kit are logically related, there are very
few physical connections that bind them together.
• Systems of interacting objects, which are collections of items (classes, metaclasses,
parameterized classes, non-class instances, kits, and/or other systems of interacting objects) all
of which support a single, large, coherent, object-oriented concept, and in which there must be a
direct or indirect physical connection between any two arbitrary objects within the collection.
Further, systems of interacting objects have at least one internal, independently executing thread
of control. Lastly, systems of interacting objects may exhibit multiple, completely disjoint public
interfaces.

Kits resemble libraries. Say, for example, that we had to create a computer application with a graphical
user interface. Graphical user interfaces normally contain several different types of windows. It would be
very useful if we had a library of windows and window components from which we could construct any
window we desired. Windows are objects, and the components of windows (buttons and check boxes)
are themselves objects. A collection of windows and window components can be viewed as a kit.

Systems of interacting objects, on the other hand, resemble applications. For example, suppose that we
wanted to construct an object-oriented application that controlled the elevators in a particular building. We
would assemble elevators, buttons, lamps, panels, and other objects into a working application that would
control the elevators. Such an application would not be viewed as a library, but as a highly cohesive
whole. The elevator controller application is a system of interacting objects.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 91 of 166


Object-Oriented Programming Concepts and C++ References

Procedural oriented programming


Source http://www.sciencehq.com/computing-technology/procedural-oriented-
programming.html
Date of 14/05/2015
Retrieval

Procedural oriented programming (pop):-

A program in a procedural language is a list of instruction where each statement tells the computer to do
something. It focuses on procedure (function) & algorithm is needed to perform the derived computation.

When program become larger, it is divided into function & each function has clearly defined purpose.
Dividing the program into functions & module is one of the cornerstones of structured programming.

E.g.:- C, basic, FORTRAN.

Characteristics of Procedural oriented programming:-

1. It focuses on process rather than data.


2. It takes a problem as a sequence of things to be done such as reading, calculating and printing.
Hence, a number of functions are written to solve a problem.
3. A program is divided into a number of functions and each function has clearly defined purpose.
4. Most of the functions share global data.
5. Data moves openly around the system from function to function.

Drawback of Procedural oriented programming (structured programming):-

1. It emphasis on doing things. Data is given a second class status even through data is the reason
for the existence of the program.
2. Since every function has complete access to the global variables, the new programmer can
corrupt the data accidentally by creating function. Similarly, if new data is to be added, all the
function needed to be modified to access the data.
3. It is often difficult to design because the components function and data structure do not model the
real world.

For example, in designing graphics user interface, we think what functions, what data structures are
needed rather than which menu, menu item and soon.

4. It is difficult to create new data types. The ability to create the new data type of its own is called
extensibility. Structured programming languages are not extensible.

To overcome the limitation of Procedural oriented programming languages Object oriented programming
languages were developed.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 92 of 166


Object-Oriented Programming Concepts and C++ References

Session 2: Basics of C++

Basic Concepts

Source http://www.cs.virginia.edu/~knabe/iic2332/c++/c++_3.html
Date of 14/05/2015
Retrieval

Before giving examples of C++ features, I will first go over some of the basic concepts of
object-oriented languages. If this discussion at first seems a bit obscure, it will become
clearer when we get to some examples.

1. Classes and objects. A class is similar to a C structure, except that the definition of the data
structure, and all of the functions that operate on the data structure are grouped together in one
place. An object is an instance of a class (an instance of the data structure); objects share the
same functions with other objects of the same class, but each object (each instance) has its own
copy of the data structure. A class thus defines two aspects of the objects: the data they contain,
and the behavior they have.
2. Member functions. These are functions which are considered part of the object and are declared
in the class definition. They are often referred to as methods of the class. In addition to member
functions, a class's behavior is also defined by:
1. What to do when you create a new object (the constructor for that object) - in other
words, initialize the object's data.
2. What to do when you delete an object (the destructor for that object).
3. Private vs. public members. A public member of a class is one that can be read or written by
anybody, in the case of a data member, or called by anybody, in the case of a member function.
A private member can only be read, written, or called by a member function of that class.

Classes are used for two main reasons: (1) it makes it much easier to organize your programs if you can
group together data with the functions that manipulate that data, and (2) the use of private members
makes it possible to do information hiding, so that you can be more confident about the way information
flows in your programs.
Classes
C++ classes are similar to C structures in many ways. In fact, a C++ struct is really a class that has only
public data members. In the following explanation of how classes work, we will use a stack class as an
example.

Member functions. Here is a (partial) example of a class with a member function and some data
members:

class Stack {
public:
void Push(int value); // Push an integer, checking for overflow.
int top; // Index of the top of the stack.
int stack[10]; // The elements of the stack.
};

void
Stack::Push(int value) {
ASSERT(top < 10); // stack should never overflow

© Aptech Ltd. Version 1.0 Page 93 of 166


Object-Oriented Programming Concepts and C++ References

stack[top++] = value;
}

This class has two data members, top and stack, and one member function, Push. The notation
class::function denotes the function member of the class class. (In the style we use, most function
names are capitalized.) The function is defined beneath it.

As an aside, note that we use a call to ASSERT to check that the stack hasn't overflowed;
ASSERT drops into the debugger if the condition is false. It is an extremely good idea for you to
use ASSERT statements liberally throughout your code to document assumptions made by your
implementation. Better to catch errors automatically via ASSERTs than to let them go by and
have your program overwrite random locations.

In actual usage, the definition of class Stack would typically go in the file stack.h and the
definitions of the member functions, like Stack::Push, would go in the file stack.cc.

If we have a pointer to a Stack object called s, we can access the top element as s->top, just as
in C. However, in C++ we can also call the member function using the following syntax:

s->Push(17);

Of course, as in C, s must point to a valid Stack object.

Inside a member function, one may refer to the members of the class by their names alone. In
other words, the class definition creates a scope that includes the member (function and data)
definitions.

Note that if you are inside a member function, you can get a pointer to the object you were called
on by using the variable this. If you want to call another member function on the same object,
you do not need to use the this pointer, however. Let's extend the Stack example to illustrate
this by adding a Full() function.

class Stack {
public:
void Push(int value); // Push an integer, checking for overflow.
bool Full(); // Returns TRUE if the stack is full, FALSE
otherwise.
int top; // Index of the lowest unused position.
int stack[10]; // A pointer to an array that holds the contents.
};

bool
Stack::Full() {
return (top == 10);
}

Now we can rewrite Push this way:

void
Stack::Push(int value) {
ASSERT(!Full());
stack[top++] = value;
}

© Aptech Ltd. Version 1.0 Page 94 of 166


Object-Oriented Programming Concepts and C++ References

We could have also written the ASSERT:

ASSERT(!(this->Full());

But in a member function, the this-> is implicit.

The purpose of member functions is to encapsulate the functionality of a type of object along with
the data that the object contains. A member function does not take up space in an object of the
class.

Private members. One can declare some members of a class to be private, which are hidden to all
but the member functions of that class, and some to be public, which are visible and accessible to
everybody. Both data and function members can be either public or private.

In our stack example, note that once we have the Full() function, we really don't need to look
at the top or stack members outside of the class - in fact, we'd rather that users of the Stack
abstraction not know about its internal implementation, in case we change it. Thus we can rewrite
the class as follows:

class Stack {
public:
void Push(int value); // Push an integer, checking for overflow.
bool Full(); // Returns TRUE if the stack is full, FALSE
otherwise.
private:
int top; // Index of the top of the stack.
int stack[10]; // The elements of the stack.
};

Before, given a pointer to a Stack object, say s, any part of the program could access s->top, in
potentially bad ways. Now, since the top member is private, only a member function, such as
Full(), can access it. If any other part of the program attempts to use s->top the compiler will
report an error.

You can have alternating public: and private: sections in a class. Before you specify either
of these, class members are private, thus the above example could have been written:

class Stack {
int top; // Index of the top of the stack.
int stack[10]; // The elements of the stack.
public:
void Push(int value); // Push an integer, checking for overflow.
bool Full(); // Returns TRUE if the stack is full, FALSE
otherwise.
};

Which form you prefer is a matter of style, but it's usually best to be explicit, so that it is obvious
what is intended. In Nachos, we make everything explicit.

What is not a matter of style: all data members of a class should be private. All operations on
data should be via that class' member functions. Keeping data private adds to the modularity of
the system, since you can redefine how the data members are stored without changing how you
access them.

© Aptech Ltd. Version 1.0 Page 95 of 166


Object-Oriented Programming Concepts and C++ References

Constructors and the operator new. In C, in order to create a new object of type Stack, one might
write:

struct Stack *s = (struct Stack *) malloc(sizeof (struct Stack));


InitStack(s, 17);

The InitStack() function might take the second argument as the size of the stack to create,
and use malloc() again to get an array of 17 integers.

The way this is done in C++ is as follows:

Stack *s = new Stack(17);

The new function takes the place of malloc(). To specify how the object should be initialized,
one declares a constructor function as a member of the class, with the name of the function being
the same as the class name:

class Stack {
public:
Stack(int sz); // Constructor: initialize variables, allocate
space.
void Push(int value); // Push an integer, checking for overflow.
bool Full(); // Returns TRUE if the stack is full, FALSE
otherwise.
private:
int size; // The maximum capacity of the stack.
int top; // Index of the lowest unused position.
int* stack; // A pointer to an array that holds the contents.
};

Stack::Stack(int sz) {
size = sz;
top = 0;
stack = new int[size]; // Let's get an array of integers.
}

There are a few things going on here, so we will describe them one at a time.

The new operator automatically creates (i.e. allocates) the object and then calls the constructor
function for the new object. This same sequence happens even if, for instance, you declare an
object as an automatic variable inside a function or block - the compiler allocates space for the
object on the stack, and calls the constructor function on it.

In this example, we create two stacks of different sizes, one by declaring it as an automatic
variable, and one by using new.

void
test() {
Stack s1(17);
Stack* s2 = new Stack(23);
}

© Aptech Ltd. Version 1.0 Page 96 of 166


Object-Oriented Programming Concepts and C++ References

Note there are two ways of providing arguments to constructors: with new, you put the argument
list after the class name, and with automatic or global variables, you put them after the variable
name.

It is crucial that you always define a constructor for every class you define, and that the
constructor initialize every data member of the class. If you don't define your own constructor, the
compiler will automatically define one for you, and believe me, it won't do what you want ("the
unhelpful compiler"). The data members will be initialized to random, unrepeatable values, and
while your program may work anyway, it might not the next time you recompile (or vice versa!).

As with normal C variables, variables declared inside a function are deallocated automatically
when the function returns; for example, the s1 object is deallocated when test returns. Data
allocated with new (such as s2) is stored on the heap, however, and remains after the function
returns; heap data must be explicitly disposed of using delete, described below.

The new operator can also be used to allocate arrays, illustrated above in allocating an array of
ints, of dimension size:

stack = new int[size];

Note that you can use new and delete (described below) with built-in types like int and char
as well as with class objects like Stack.

Destructors and the operator delete. Just as new is the replacement for malloc(), the
replacement for free() is delete. To get rid of the Stack object we allocated above with new,
one can do:

delete s2;

This will deallocate the object, but first it will call the destructor for the Stack class, if there is
one. This destructor is a member function of Stack called ~Stack():

class Stack {
public:
Stack(int sz); // Constructor: initialize variables, allocate
space.
~Stack(); // Destructor: deallocate space allocated
above.
void Push(int value); // Push an integer, checking for overflow.
bool Full(); // Returns TRUE if the stack is full, FALSE
otherwise.
private:
int size; // The maximum capacity of the stack.
int top; // Index of the lowest unused position.
int* stack; // A pointer to an array that holds the contents.
};

Stack::~Stack() {
delete [] stack; // delete an array of integers
}

The destructor has the job of deallocating the data the constructor allocated. Many classes won't
need destructors, and some will use them to close files and otherwise clean up after themselves.

© Aptech Ltd. Version 1.0 Page 97 of 166


Object-Oriented Programming Concepts and C++ References

The destructor for an object is called when the object is deallocated. If the object was created
with new, then you must call delete on the object, or else the object will continue to occupy
space until the program is over - this is called "a memory leak." Memory leaks are bad things -
although virtual memory is supposed to be unlimited, you can in fact run out of it - and so you
should be careful to always delete what you allocate. Of course, it is even worse to call delete
too early - delete calls the destructor and puts the space back on the heap for later re-use. If
you are still using the object, you will get random and non-repeatable results that will be very
difficult to debug. In my experience, using data that has already been deleted is major source of
hard-to-locate bugs in student (and professional) programs, so hey, be careful out there!

If the object is an automatic, allocated on the execution stack of a function, the destructor will be
called and the space deallocated when the function returns; in the test() example above, s1
will be deallocated when test() returns, without you having to do anything.

In Nachos, we always explicitly allocate and deallocate objects with new and delete, to make it
clear when the constructor and destructor is being called. For example, if an object contains
another object as a member variable, we use new to explicitly allocated and initialize the member
variable, instead of implicitly allocating it as part of the containing object. C++ has strange, non-
intuitive rules for the order in which the constructors and destructors are called when you
implicitly allocate and deallocate objects. In practice, although simpler, explicit allocation is
slightly slower and it makes it more likely that you will forget to deallocate an object (a bad thing!),
and so some would disagree with this approach.

When you deallocate an array, you have to tell the compiler that you are deallocating an array, as
opposed to a single element in the array. Hence to delete the array of integers in
Stack::~Stack:

delete [] stack;
Other Basic C++ Features
Here are a few other C++ features that are useful to know.

1. When you define a class Stack, the name Stack becomes usable as a type name as if created
with typedef. The same is true for enums.
2. You can define functions inside of a class definition, whereupon they become inline functions,
which are expanded in the body of the function where they are used. The rule of thumb to follow
is to only consider inlining one-line functions, and even then do so rarely.

As an example, we could make the Full routine an inline.

class Stack {
...
bool Full() { return (top == size); };
...
};

There are two motivations for inlines: convenience and performance. If overused, inlines can
make your code more confusing, because the implementation for an object is no longer in one
place, but spread between the .h and .c files. Inlines can sometimes speed up your code (by
avoiding the overhead of a procedure call), but that shouldn't be your principal concern as a
student (rather, at least to begin with, you should be most concerned with writing code that is
simple and bug free). Not to mention that inlining sometimes slows down a program, since the
object code for the function is duplicated wherever the function is called, potentially hurting cache
performance.

© Aptech Ltd. Version 1.0 Page 98 of 166


Object-Oriented Programming Concepts and C++ References

3. Inside a function body, you can declare some variables, execute some statements, and then
declare more variables. This can make code a lot more readable. In fact, you can even write
things like:

for (int i = 0; i < 10; i++) ;

Depending on your compiler, however, the variable i may still visible after the end of the for loop,
however, which is not what one might expect or desire.

4. Comments can begin with the characters // and extend to the end of the line. These are usually
more handy than the /* */ style of comments.
5. C++ provides some new opportunities to use the const keyword from ANSI C. The basic idea of
const is to provide extra information to the compiler about how a variable or function is used, to
allow it to flag an error if it is being used improperly. You should always look for ways to get the
compiler to catch bugs for you. After all, which takes less time? Fixing a compiler-flagged error, or
chasing down the same bug using gdb?

For example, you can declare that a member function only reads the member data, and never
modifies the object:

class Stack {
...
bool Full() const; // Full() never modifies member data
...
};

As in C, you can use const to declare that a variable is never modified:

const int InitialHashTableSize = 8;

This is much better than using #define for constants, since the above is type-checked.

6. Input/output in C++ can be done with the >> and << operators and the objects cin and cout.
For example, to write to stdout:

cout << "Hello world! This is section " << 3 << "!";

This is equivalent to the normal C code

fprintf(stdout, "Hello world! This is section %d!\n", 3);

except that the C++ version is type-safe; with printf, the compiler won't complain if you try to
print a floating point number as an integer. In fact, you can use traditional printf in a C++
program, but you will get bizarre behavior if you try to use both printf and << on the same
stream. Reading from stdin works the same way as writing to stdout, except using the shift
right operator instead of shift left. In order to read two integers from stdin:

int field1, field2;


cin >> field1 >> field2;
// equivalent to fscanf(stdin, "%d %d", &field1, &field2);
// note that field1 and field2 are implicitly modified

© Aptech Ltd. Version 1.0 Page 99 of 166


Object-Oriented Programming Concepts and C++ References

In fact, cin and cout are implemented as normal C++ objects, using operator overloading and
reference parameters, but (fortunately!) you don't need to understand either of those to be able to
do I/O in C++.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 100 of 166


Object-Oriented Programming Concepts and C++ References

The basics of C++

Source http://www.cs.virginia.edu/~knabe/iic2332/c++/c++_3.html
Date of 14/05/2015
Retrieval

This tutorial series is designed for everyone: even if you've never programmed before or if you have
extensive experience programming in other languages and want to expand into C++! It is for everyone
who wants the feeling of accomplishment from a working program.

What do I mean? C++ is a programming language--it will allow you to control your computer, making it do
what you want it to do. This programming tutorial series is all about helping you take advantage of C++.

Getting Set Up - C++ Compilers


The very first thing you need to do, before starting out in C++, is to make sure that you have a compiler.
What is a compiler, you ask? A compiler turns the program that you write into an executable that your
computer can actually understand and run. If you're taking a course, you probably have one provided
through your school. If you're starting out on your own, your best bet is to use Code::Blocks with MinGW.
If you're on Linux, you can use g++, and if you're on Mac OS X, you can use XCode. (If you are stuck
using an older compiler, such as Turbo C++, you'll need to read this page on compatibility issues.) If you
haven't yet done so, go ahead and get a compiler set up--you'll need it for the rest of the tutorial.

Intro to the C++ Language


A C++ program is a collection of commands, which tell the computer to do "something". This collection of
commands is usually called C++ source code, source code or just code. Commands are either
"functions" or "keywords". Keywords are a basic building block of the language, while functions are, in
fact, usually written in terms of simpler functions--you'll see this in our very first program, below.
(Confused? Think of it a bit like an outline for a book; the outline might show every chapter in the book;
each chapter might have its own outline, composed of sections. Each section might have its own outline,
or it might have all of the details written up.) Thankfully, C++ provides a great many common functions
and keywords that you can use.

But how does a program actually start? Every program in C++ has one function, always named main,
that is always called when your program first executes. From main, you can also call other functions
whether they are written by us or, as mentioned earlier, provided by the compiler.

So how do you get access to those prewritten functions? To access those standard functions that comes
with the compiler, you include a header with the #include directive. What this does is effectively take
everything in the header and paste it into your program. Let's look at a working program:
#include <iostream>
using namespace std;
int main()
{
cout<<"HEY, you, I'm alive! Oh, and Hello World!\n";
cin.get();
}
Let's look at the elements of the program. The #include is a "preprocessor" directive that tells the compiler
to put code from the header called iostream into our program before actually creating the executable. By

© Aptech Ltd. Version 1.0 Page 101 of 166


Object-Oriented Programming Concepts and C++ References

including header files, you gain access to many different functions. For example, the cout function
requires iostream. Following the include is the statement, "using namespace std;". This line tells the
compiler to use a group of functions that are part of the standard library (std). By including this line at the
top of a file, you allow the program to use functions such as cout. The semicolon is part of the syntax of
C++. It tells the compiler that you're at the end of a command. You will see later that the semicolon is
used to end most commands in C++.

The next important line is int main(). This line tells the compiler that there is a function named main, and
that the function returns an integer, hence int. The "curly braces" ({ and }) signal the beginning and end of
functions and other code blocks. You can think of them as meaning BEGIN and END.

The next line of the program may seem strange. If you have programmed in another language, you might
expect that print would be the function used to display text. In C++, however, the cout object is used to
display text (pronounced "C out"). It uses the << symbols, known as "insertion operators", to indicate what
to output. cout<< results in a function call with the ensuing text as an argument to the function. The
quotes tell the compiler that you want to output the literal string as-is. The '\n' sequence is actually treated
as a single character that stands for a newline (we'll talk about this later in more detail). It moves the
cursor on your screen to the next line. Again, notice the semicolon: it is added onto the end of most lines,
such as function calls, in C++.

The next command is cin.get(). This is another function call: it reads in input and expects the user to hit
the return key. Many compiler environments will open a new console window, run the program, and then
close the window. This command keeps that window from closing because the program is not done yet
because it waits for you to hit enter. Including that line gives you time to see the program run.

Upon reaching the end of main, the closing brace, our program will return the value of 0 (and integer,
hence why we told main to return an int) to the operating system. This return value is important as it can
be used to tell the OS whether our program succeeded or not. A return value of 0 means success and is
returned automatically (but only for main, other functions require you to manually return a value), but if we
wanted to return something else, such as 1, we would have to do it with a return statement:
#include <iostream>

using namespace std;

int main()
{
cout<<"HEY, you, I'm alive! Oh, and Hello World!\n";
cin.get();

return 1;
}
The final brace closes off the function. You should try compiling this program and running it. You can cut
and paste the code into a file, save it as a .cpp file. Our Code::Blocks tutorial actually takes you through
creating a simple program, so check it out if you're confused.

If you are not using Code::Blocks, you should read the compiler instructions for information on how to
compile.
Once you've got your first program running, why don't you try playing around with the cout function to get
used to writing C++?

© Aptech Ltd. Version 1.0 Page 102 of 166


Object-Oriented Programming Concepts and C++ References

An Aside on Commenting Your Programs


As you are learning to program, you should also start to learn how to explain your programs (for yourself,
if no one else). You do this by adding comments to code; I'll use them frequently to help explain code
examples.

When you tell the compiler a section of text is a comment, it will ignore it when running the code, allowing
you to use any text you want to describe the real code. To create a comment use either //, which tells the
compiler that the rest of the line is a comment, or /* and then */ to block off everything between as a
comment. Certain compiler environments will change the color of a commented area, but some will not.
Be certain not to accidentally comment out code (that is, to tell the compiler part of your code is a
comment) you need for the program. When you are learning to program, it is useful to be able to
comment out sections of code in order to see how the output is affected.

User interaction and Saving Information with Variables


So far you've learned how to write a simple program to display information typed in by you, the
programmer, and how to describe your program with comments. That's great, but what about interacting
with your user? Fortunately, it is also possible for your program to accept input. The function you use is
known as cin, and is followed by the extraction operator >>.

Of course, before you try to receive input, you must have a place to store that input. In programming,
input and data are stored in variables. There are several different types of variables which store different
kinds of information (e.g. numbers versus letters); when you tell the compiler you are declaring a variable,
you must include the data type along with the name of the variable. Several basic types include char, int,
and float.

A variable of type char stores a single character, variables of type int store integers (numbers without
decimal places), and variables of type float store numbers with decimal places. Each of these variable
types - char, int, and float - is each a keyword that you use when you declare a variable.

What's with all these variable types?


Sometimes it can be confusing to have multiple variable types when it seems like some variable types are
redundant (why have integer numbers when you have floats?). Using the right variable type can be
important for making your code readable and for efficiency--some variables require more memory than
others. Moreover, because of the way the numbers are actually stored in memory, a float is "inexact", and
should not be used when you need to store an "exact" integer value.

Declaring Variables in C++


To declare a variable you use the syntax "type <name>;". Here are some variable declaration examples:
int x;
char letter;
float the_float;

It is permissible to declare multiple variables of the same type on the same line; each one should be
separated by a comma.
int a, b, c, d;
If you were watching closely, you might have seen that declaration of a variable is always followed by a
semicolon (note that this is the same procedure used when you call a function).

Common Errors when Declaring Variables in C++


If you attempt to use a variable that you have not declared, your program will not be compiled or run, and
you will receive an error message informing you that you have made a mistake. Usually, this is called an
undeclared variable.

© Aptech Ltd. Version 1.0 Page 103 of 166


Object-Oriented Programming Concepts and C++ References

Case Sensitivity
Now is a good time to talk about an important concept that can easily throw you off: case sensitivity.
Basically, in C++, whether you use uppercase or lowercase letters matters. The words Cat and cat mean
different things to the compiler. In C++, all language keywords, all functions and all variables are case
sensitive. A difference in case between your variable declaration and the use of the variable is one
reason you might get an undeclared variable error.

Using Variables
Ok, so you now know how to tell the compiler about variables, but what about using them?

Here is a sample program demonstrating the use of a variable:


#include <iostream>

using namespace std;

int main()
{
int thisisanumber;

cout<<"Please enter a number: ";


cin>> thisisanumber;
cin.ignore();
cout<<"You entered: "<< thisisanumber <<"\n";
cin.get();
}

Let's break apart this program and examine it line by line. The keyword int declares thisisanumber to be
an integer. The function cin>> reads a value into thisisanumber; the user must press enter before the
number is read by the program. cin.ignore() is another function that reads and discards a character.
Remember that when you type input into a program, it takes the enter key too. We don't need this, so we
throw it away. Keep in mind that the variable was declared an integer; if the user attempts to type in a
decimal number, it will be truncated (that is, the decimal component of the number will be ignored). Try
typing in a sequence of characters or a decimal number when you run the example program; the
response will vary from input to input, but in no case is it particularly pretty. Notice that when printing out a
variable quotation marks are not used. Were there quotation marks, the output would be "You Entered:
thisisanumber." The lack of quotation marks informs the compiler that there is a variable, and therefore
that the program should check the value of the variable in order to replace the variable name with the
variable when executing the output function. Do not be confused by the inclusion of two separate
insertion operators on one line. Including multiple insertion operators on one line is perfectly acceptable
and all of the output will go to the same place. In fact, you must separate string literals (strings enclosed
in quotation marks) and variables by giving each its own insertion operators (<<). Trying to put two
variables together with only one << will give you an error message, do not try it. Do not forget to end
functions and declarations with a semicolon. If you forget the semicolon, the compiler will give you an
error message when you attempt to compile the program.

Changing and Comparing Variables


Of course, no matter what type you use, variables are uninteresting without the ability to modify them.
Several operators used with variables include the following: *, -, +, /, =, ==, >, <. The * multiplies, the -
subtracts, and the + adds. It is of course important to realize that to modify the value of a variable inside
the program it is rather important to use the equal sign. In some languages, the equal sign compares the
value of the left and right values, but in C++ == is used for that task. The equal sign is still extremely
useful. It sets the left input to the equal sign, which must be one, and only one, variable equal to the value
on the right side of the equal sign. The operators that perform mathematical functions should be used on

© Aptech Ltd. Version 1.0 Page 104 of 166


Object-Oriented Programming Concepts and C++ References

the right side of an equal sign in order to assign the result to a variable on the left side.

Here are a few examples:


a = 4 * 6; // (Note use of comments and of semicolon) a is 24
a = a + 5; // a equals the original value of a with five added to it
a == 5 // Does NOT assign five to a. Rather, it checks to see if a equals 5.

The other form of equal, ==, is not a way to assign a value to a variable. Rather, it checks to see if the
variables are equal. It is useful in other areas of C++; for example, you will often use == in such
constructions as conditional statements and loops. You can probably guess how < and > function. They
are greater than and less than operators.

For example:
a < 5 // Checks to see if a is less than five
a > 5 // Checks to see if a is greater than five
a == 5 // Checks to see if a equals five, for good measure

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 105 of 166


Object-Oriented Programming Concepts and C++ References

Session 3: Flow Control Statements

Decisions, Decisions: Making Choices in C++


Source http://cis.stvincent.edu/html/tutorials/swd/basic/control/branching/index.html
Date of 14/05/2015
Retrieval

Introduction

There must be a way to make a decision within a program about whether to execute certain statements or
not, or perhaps to decide whether to do one section of code or to do another section instead. We examine
how to use the C++ if and switch constructs to make choices about what to do during the execution of
a program.

An All or Nothing Choice

Here the choice is whether to do a section of code or to skip it entirely. For example, consider the
following:

if (Num > 0)
Num = Num * 10;
cout << Num << endl;

If the value in Num is positive, we assign into it 10 times its value. Then we go on to whatever follows
next after the if statement. In this case, we print out the value of Num. Note that the code that is
selected is the single statement following the if (CONDITION) construct. Should you want to have
multiple statements governed by the if, you package up those statements as a block by placing curly
braces around them. We will look at an example of that shortly.

If the value of Num is not positive, then the assignment statement is skipped. Control passes on to the
output statement that follows. Thus if Num has value -2, the above example prints -2, but if Num has
value 3, it prints 30, because the number gets multiplied by 10.

Now consider the following similar example. This time the if selects whether or not to do an entire block
of code, which is enclosed in curly braces.

if (Num > 0)
{
Num = Num * 10;
cout << "Multiplying by 10" << endl;
}
cout << Num << endl;

© Aptech Ltd. Version 1.0 Page 106 of 166


Object-Oriented Programming Concepts and C++ References

Can you tell what this section of code does? If Num has value -2, this example prints the -2 on the screen.
However, if Num has value 3, the following would be printed:

Multiplying by 10
30

Note that the code that is controlled by the if is indented by 3 spaces. The curly braces should line up
vertically. That way one can easily see where this important section of code begins and ends.

See the example choice1.cpp. It shows a small but complete program that contains an all or nothing
choice.

Conditions

True/false conditions are needed to control if statements. These can be constructed in a number of ways.
One way is by comparing two expressions with a relational operator such as <, >, == (equals), != (not
equal), <=, or >=. For example, consider the following:

x < y
Top - Bottom >= 12
Value == Max

The first example condition checks to see if x is less than y. The second one checks to see if Top minus
Bottom is greater or equal to 12. Finally, the last one checks to see if Value and Max are equal. Note
well that you need two equals signs for an equals comparison. A single equals sign gives an assignment
statement, which is quite a different thing!

To Do This or That

This type of choice is usually made with an if..else... construct. If the condition is true, the first
section of code is executed. If not, the second section of code (the one following the else) is executed. In
either case, after the appropriate section of code has been executed, control passes to whatever follows
the entire if..else... construct. If a section of code for one of the choices consists of more than one
statement, then those statements must be packaged up as a block by using curly braces.

The following example shows such a two-way choice. Depending on the value of the variable, either
positive or not positive is printed. Then, either way, a final message is printed.

if (Num > 0)
cout << "positive" << endl;
else
cout << "not positive" << endl;
cout << "In all cases we reach here and print this message.";

© Aptech Ltd. Version 1.0 Page 107 of 166


Object-Oriented Programming Concepts and C++ References

Compound Conditions

Two or more conditions can be combined by using the boolean operators && (AND), || (OR), ! (NOT).
NOT reverses the truth value of the condition to which it is applied. The result of ANDing or ORing two
conditions is most easily summarized in a truth table as shown below. A AND B is only true when both A
and B are true. A OR B is only false when both are false.

A B A AND B A OR B

True True True True

True False False True

False True False True

False False False False

For example, suppose we want to test if a number grade is within the valid range of 0 to 100. This might
be done with a compound condition as follows:

if ((Num >= 0) && (Num <= 100))


{
// Num is valid, so we do whatever processing we want to on Num here.
// Code for this is not shown.
}
else
cout << "Invalid number grade" << endl;

The above program fragment is equivalent to the following. Note the use of ! for NOT and the || for OR. It
uses these to write a condition that checks to see that the value of the variable is not invalid. Note that
because of the parentheses the NOT applies to the OR of the two conditions, that is, the NOT applies to
((Num < 0) || (Num > 100)).

if (! ((Num < 0) || (Num > 100)))


{
// Num is valid, so we do whatever processing we want to on Num here.
// Code for this is not shown.
}
else
cout << "Invalid number grade" << endl;

Boolean Variables

Boolean variables are of type bool. Such a variable can at any point take on just one of two
possible values: true or false. Here is an outline of a simple example:

© Aptech Ltd. Version 1.0 Page 108 of 166


Object-Oriented Programming Concepts and C++ References

bool Error;
Error = false;

if (such and such goes wrong)


Error = true;
else
Do some processing of data;

Do some other stuff in all cases;

if (Error)
cout << "An error has been reported" << endl;
else
cout << "All is OK" << endl;

In this example, the Error variable is used to remember whether or not an error happened. Later, when
some output about the status of the program is desired, this variable can be testing in an if statement to
decide what to print. Boolean variables are great for storing true/false, yes/no types of information. If you
want to check if a boolean variable, such as Error is not true, use something like this:

if (! Error)
cout << "No error has been found" << endl;
else
cout << "An error has been reported" << endl;

Multiway Choices

Sometimes you need to decide among multiple possibilities. This requires at least two
conditions. The extended if itself looks like this:

if (Num > 0)
cout << " is positive" << endl << endl;
else if (Num == 0)
cout << " is zero" << endl << endl;
else
cout << " is negative" << endl << endl;

Note that the else if combination is new. How does this example work? If the first condition is true, the
first section of code is executed and the rest is skipped. If not, the second condition is tried. If it is true,
the second section of code is executed and the rest is skipped. If the second condition is found to be
false, the third section of code is executed. No matter which of the 3 sections of code is executed, control
then passes to whatever follows the extended if construct. Note the indenting pattern. The indenting
of the 3 sections of code makes it easy to see at a glance what the 3 choices are.

© Aptech Ltd. Version 1.0 Page 109 of 166


Object-Oriented Programming Concepts and C++ References

The extended if can be continued further to handle as many choices as you like. For example,
suppose you ask the user to press a letter to indicate a selection from a program menu. You can then use
an extended if to select the correct section of code to execute. This might look like the following:

char Choice;
cout << "Enter the letter for your choice: ";
cin >> Choice;

if (Choice == 'A')
DoA();
else if (Choice == 'B')
DoB();
else if (Choice == 'C')
DoC();
else if (Choice == 'D')
DoD();

The above code assumes that we have written functions called DoA, DoB, etc. to carry out the desired
actions. We could add an else clause to catch anything other than A, B, C, or D and write out an error
message in such a case, if we wanted. You might also wonder why we didn't write the above code using
separate if statements. This could, in fact, be done and would look like the following:

char Choice;
cout << "Enter the letter for your choice: ";
cin >> Choice;

if (Choice == 'A')
DoA();

if (Choice == 'B')
DoB();

if (Choice == 'C')
DoC();

if (Choice == 'D')
DoD();

The blank lines between the separate if statements are not necessary, but they help to make it clear that
these are indeed separate if statements. Which of these two ways of handling the choice of A, B, C, or
D is better? Both methods clearly work. One way to tell is to draw a decision tree for each method,
showing in each case the choices that are possible:

© Aptech Ltd. Version 1.0 Page 110 of 166


Object-Oriented Programming Concepts and C++ References

In each tree, the conditions are labelled with a question mark. If the answer to a question is yes, then the
branch to the left is taken. If the answer to a question is no, then the branch to the right is taken. In the
decision tree for the extended if it is clear that in some cases only one condition is checked, in other
cases two conditions are checked before the correct code is selected, in others three conditions are
checked, and sometimes all four conditions are checked. On average, though, fewer than all 4 conditions
are tested. In the other method, all 4 conditions are always checked. This is needless and a waste of
time. Once we know that the variable has A in it, there is no need to check to see if it is a B, etc. Thus our
decision trees have helped us to conclude that the extended if pattern is more efficient that
separate ifs. In general, you should not use separate ifs when an extended if can be used
instead.

The Switch

This construct provides an alternate way to handle multiway choices when the conditions are based on
equality. For example, in the following code we want to choose to call one of 4 functions based on
whether variable Choice equals A, B, C, or D (or their lower case equivalents).

char Choice;
cout << "Enter the letter for your choice: ";
cin >> Choice;

switch(Choice)
{
case 'A':
case 'a':
DoOptionA();
break;
case 'B':
case 'b':
DoOptionB();
break;
case 'C':
case 'c':
DoOptionC();

© Aptech Ltd. Version 1.0 Page 111 of 166


Object-Oriented Programming Concepts and C++ References

break;
case 'D':
case 'd':
DoOptionD();
}

Note that everything in the switch is enclosed in curly braces, but that braces are not needed around the
code blocks among which we are choosing. When the switch is executed it checks the value of the
variable listed in the switch() with each case in order. If a match is found, it then executes the code
below that case. Typically the section of code ends with a break statement which takes us to whatever
follows the entire switch construct. If there is no break at the end of the section of code, control passes
right into the next section of code, whether or not the variable matches the case at the head of this
section of code! That is why the break statements above are so important. There is no need of a break
after the code for the last case as we will exit from the switch construct after executing this code anyway.
If the value of the variable doesn't match any of the cases in the switch construct, then the entire
construct is skipped over.

Let's look at a variation on the above example in which we use an integer variable instead of a character
variable. Although we could read in 1, 2, 3, or 4 into a character variable, it would be more typical to read
them into an integer variable. (Besides, we could not read in a multi-character item like 12 into a single-
character variable, so an integer variable is better here.) Note that literal character values are written with
single quotes around them as in '2', whereas literal integer or float values are written without quotes as in
2.

int Num;
cout << "Enter the number for your choice: ";
cin >> Choice;

switch(Num)
{
case 1:
DoOption1();
break;
case 2:
DoOption2();
break;
case 3:
DoOption3();
break;
case 4:
DoOption4();
break;
default:
cout << "Invalid number was entered" << endl;
}

© Aptech Ltd. Version 1.0 Page 112 of 166


Object-Oriented Programming Concepts and C++ References

This example also illustrates the default case. If the value of Num doesn't match any of the other
cases, then the code for the default case is executed.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 113 of 166


Object-Oriented Programming Concepts and C++ References

Session 4: Functions, Pointers, and Arrays

Functions

Source http://www.cprogramming.com/tutorial/lesson4.html
Date of 14/05/2015
Retrieval

Now that you should have learned about variables, loops, and conditional statements it is time to learn
about functions. You should have an idea of their uses as we have already used them and defined one in
the guise of main. cin.get() is an example of a function. In general, functions are blocks of code that
perform a number of pre-defined commands to accomplish something productive.

Now that you should have learned about variables, loops, and conditional statements it is time to learn
about functions. You should have an idea of their uses as we have already used them and defined one
in the guise of main. cin.get() is an example of a function. In general, functions are blocks of code
that perform a number of pre-defined commands to accomplish something productive.

Functions that a programmer writes will generally require a prototype. Just like a blueprint, the
prototype tells the compiler what the function will return, what the function will be called, as well as what
arguments the function can be passed. When I say that the function returns a value, I mean that the
function can be used in the same manner as a variable would be. For example, a variable can be set
equal to a function that returns a value between zero and four.

For example:

#include <cstdlib> // Include rand()

using namespace std; // Make rand() visible

int a = rand(); // rand is a standard function that all compilers have


Do not think that 'a' will change at random, it will be set to the value returned when the function is
called, but it will not change again.

The general format for a prototype is simple:


return-type function_name ( arg_type arg1, ..., arg_type argN );
arg_type just means the type for each argument -- for instance, an int, a float, or a char. It's exactly the
same thing as what you would put if you were declaring a variable.

There can be more than one argument passed to a function or none at all (where the parentheses are
empty), and it does not have to return a value. Functions that do not return values have a return type of
void. Let's look at a function prototype:
int mult ( int x, int y );
This prototype specifies that the function mult will accept two arguments, both integers, and that it will
return an integer. Do not forget the trailing semi-colon. Without it, the compiler will probably think that
you are trying to write the actual definition of the function.

© Aptech Ltd. Version 1.0 Page 114 of 166


Object-Oriented Programming Concepts and C++ References

When the programmer actually defines the function, it will begin with the prototype, minus the semi-
colon. Then there should always be a block with the code that the function is to execute, just as you
would write it for the main function. Any of the arguments passed to the function can be used as if they
were declared in the block. Finally, end it all with a cherry and a closing brace. Okay, maybe not a
cherry.

Let's look at an example program:


#include <iostream>

using namespace std;

int mult ( int x, int y );

int main()
{
int x;
int y;

cout<<"Please input two numbers to be multiplied: ";


cin>> x >> y;
cin.ignore();
cout<<"The product of your two numbers is "<< mult ( x, y ) <<"\n";
cin.get();
}

int mult ( int x, int y )


{
return x * y;
}
This program begins with the only necessary include file and a directive to make the std namespace
visible. Everything in the standard headers is inside of the std namespace and not visible to our
programs unless we make them so. Next is the prototype of the function. Notice that it has the final
semi-colon! The main function returns an integer, which you should always have to conform to the
standard. You should not have trouble understanding the input and output functions. It is fine to use cin
to input to variables as the program does. But when typing in the numbers, be sure to separate them by
a space so that cin can tell them apart and put them in the right variables.

Notice how cout actually outputs what appears to be the mult function. What is really happening is cout
is printing the value returned by mult, not mult itself. The result would be the same as if we had use this
print instead
cout<<"The product of your two numbers is "<< x * y <<"\n";
The mult function is actually defined below main. Due to its prototype being above main, the compiler
still recognizes it as being defined, and so the compiler will not give an error about mult being
undefined. As long as the prototype is present, a function can be used even if there is no definition.
However, the code cannot be run without a definition even though it will compile. The prototype and
definition can be combined into one also. If mult were defined before it is used, we could do away with
the prototype because the definition can act as a prototype as well.

Return is the keyword used to force the function to return a value. Note that it is possible to have a
function that returns no value. If a function returns void, the return statement is valid, but only if it does
not have an expression. In other words, for a function that returns void, the statement "return;" is legal,
but redundant.

The most important functional (Pun semi-intended) question is why do we need a function? Functions
have many uses. For example, a programmer may have a block of code that he has repeated forty

© Aptech Ltd. Version 1.0 Page 115 of 166


Object-Oriented Programming Concepts and C++ References

times throughout the program. A function to execute that code would save a great deal of space, and it
would also make the program more readable. Also, having only one copy of the code makes it easier to
make changes. Would you rather make forty little changes scattered all throughout a potentially large
program, or one change to the function body? So would I.

Another reason for functions is to break down a complex program into logical parts. For example, take
a menu program that runs complex code when a menu choice is selected. The program would probably
best be served by making functions for each of the actual menu choices, and then breaking down the
complex tasks into smaller, more manageable tasks, which could be in their own functions. In this way,
a program can be designed that makes sense when read. And has a structure that is easier to
understand quickly. The worst programs usually only have the required function, main, and fill it with
pages of jumbled code.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 116 of 166


Object-Oriented Programming Concepts and C++ References

Pointers in C++

Source http://www.cprogramming.com/tutorial/lesson6.html
Date of 14/05/2015
Retrieval

Pointers are an extremely powerful programming tool. They can make some things much easier, help
improve your program's efficiency, and even allow you to handle unlimited amounts of data. For example,
using pointers is one way to have a function modify a variable passed to it. It is also possible to use
pointers to dynamically allocate memory, which means that you can write programs that can handle
nearly unlimited amounts of data on the fly--you don't need to know, when you write the program, how
much memory you need. Wow, that's kind of cool. Actually, it's very cool, as we'll see in some of the next
tutorials. For now, let's just get a basic handle on what pointers are and how you use them.

Pointers are an extremely powerful programming tool. They can make some things much easier, help
improve your program's efficiency, and even allow you to handle unlimited amounts of data. For
example, using pointers is one way to have a function modify a variable passed to it. It is also possible
to use pointers to dynamically allocate memory, which means that you can write programs that can
handle nearly unlimited amounts of data on the fly--you don't need to know, when you write the
program, how much memory you need. Wow, that's kind of cool. Actually, it's very cool, as we'll see in
some of the next tutorials. For now, let's just get a basic handle on what pointers are and how you use
them.

What are pointers? Why should you care?


Pointers are aptly named: they "point" to locations in memory. Think of a row of safety deposit boxes of
various sizes at a local bank. Each safety deposit box will have a number associated with it so that the
teller can quickly look it up. These numbers are like the memory addresses of variables. A pointer in the
world of safety deposit boxes would simply be anything that stored the number of another safety
deposit box. Perhaps you have a rich uncle who stored valuables in his safety deposit box, but decided
to put the real location in another, smaller, safety deposit box that only stored a card with the number of
the large box with the real jewelry. The safety deposit box with the card would be storing the location of
another box; it would be equivalent to a pointer. In the computer, pointers are just variables that store
memory addresses, usually the addresses of other variables.

The cool thing is that once you can talk about the address of a variable, you'll then be able to go to that
address and retrieve the data stored in it. If you happen to have a huge piece of data that you want to
pass into a function, it's a lot easier to pass its location to the function than to copy every element of the
data! Moreover, if you need more memory for your program, you can request more memory from the
system--how do you get "back" that memory? The system tells you where it is located in memory; that
is to say, you get a memory address back. And you need pointers to store the memory address.

A note about terms: the word pointer can refer either to a memory address itself, or to a variable that
stores a memory address. Usually, the distinction isn't really that important: if you pass a pointer
variable into a function, you're passing the value stored in the pointer--the memory address. When I
want to talk about a memory address, I'll refer to it as a memory address; when I want a variable that
stores a memory address, I'll call it a pointer. When a variable stores the address of another variable, I'll
say that it is "pointing to" that variable.
C++ Pointer Syntax
Pointers require a bit of new syntax because when you have a pointer, you need the ability to request
both the memory location it stores and the value stored at that memory location. Moreover, since

© Aptech Ltd. Version 1.0 Page 117 of 166


Object-Oriented Programming Concepts and C++ References

pointers are somewhat special, you need to tell the compiler when you declare your pointer variable
that the variable is a pointer, and tell the compiler what type of memory it points to.

The pointer declaration looks like this:


<variable_type> *<name>;
For example, you could declare a pointer that stores the address of an integer with the following syntax:
int *points_to_integer;
Notice the use of the *. This is the key to declaring a pointer; if you add it directly before the variable
name, it will declare the variable to be a pointer. Minor gotcha: if you declare multiple pointers on the
same line, you must precede each of them with an asterisk:
// one pointer, one regular int
int *pointer1, nonpointer1;

// two pointers
int *pointer1, *pointer2;
As I mentioned, there are two ways to use the pointer to access information: it is possible to have it give
the actual address to another variable. To do so, simply use the name of the pointer without the *.
However, to access the actual memory location and the value stored there, use the *. The technical
name for this doing this is dereferencing the pointer; in essence, you're taking the reference to some
memory address and following it, to retrieve the actual value. It can be tricky to keep track of when you
should add the asterisk. Remember that the pointer's natural use is to store a memory address; so
when you use the pointer:
call_to_function_expecting_memory_address(pointer);
then it evaluates to the address. You have to add something extra, the asterisk, in order to retrieve the
value stored at the address. You'll probably do that an awful lot. Nevertheless, the pointer itself is
supposed to store an address, so when you use the bare pointer, you get that address back.
Pointing to Something: Retrieving an Address
In order to have a pointer actually point to another variable it is necessary to have the memory address
of that variable also. To get the memory address of a variable (its location in memory), put the & sign in
front of the variable name. This makes it give its address. This is called the address-of operator,
because it returns the memory address. Conveniently, both ampersand and address-of start with a;
that's a useful way to remember that you use & to get the address of a variable.

For example:
#include <iostream>

using namespace std;

int main()
{
int x; // A normal integer
int *p; // A pointer to an integer

p = &x; // Read it, "assign the address of x to p"


cin>> x; // Put a value in x, we could also use *p here
cin.ignore();
cout<< *p <<"\n"; // Note the use of the * to get the value
cin.get();
}
The cout outputs the value stored in x. Why is that? Well, let's look at the code. The integer is called x.
A pointer to an integer is then defined as p. Then it stores the memory location of x in pointer by using
the address-of operator (&) to get the address of the variable. Using the ampersand is a bit like looking
at the label on the safety deposit box to see its number rather than looking inside the box, to get what it

© Aptech Ltd. Version 1.0 Page 118 of 166


Object-Oriented Programming Concepts and C++ References

stores. The user then inputs a number that is stored in the variable x; remember, this is the same
location that is pointed to by p.

The next line then passes *p into cout. *p performs the "dereferencing" operation on p; it looks at the
address stored in p, and goes to that address and returns the value. This is akin to looking inside a
safety deposit box only to find the number of (and, presumably, the key to ) another box, which you
then open.

Notice that in the above example, pointer is initialized to point to a specific memory address before it is
used. If this was not the case, it could be pointing to anything. This can lead to extremely unpleasant
consequences to the program. For instance, the operating system will probably prevent you from
accessing memory that it knows your program doesn't own: this will cause your program to crash. To
avoid crashing your program, you should always initialize pointers before you use them.

It is also possible to initialize pointers using free memory. This allows dynamic allocation of array
memory. It is most useful for setting up structures called linked lists. This difficult topic is too complex
for this text. An understanding of the keywords new and delete will, however, be tremendously helpful
in the future.

The keyword new is used to initialize pointers with memory from free store (a section of memory
available to all programs). The syntax looks like the example:
int *ptr = new int;
It initializes ptr to point to a memory address of size int (because variables have different sizes, number
of bytes, this is necessary). The memory that is pointed to becomes unavailable to other programs.
This means that the careful coder should free this memory at the end of its usage.

The delete operator frees up the memory allocated through new. To do so, the syntax is as in the
example.
delete ptr;
After deleting a pointer, it is a good idea to reset it to point to 0. When 0 is assigned to a pointer, the
pointer becomes a null pointer, in other words, it points to nothing. By doing this, when you do
something foolish with the pointer (it happens a lot, even with experienced programmers), you find out
immediately instead of later, when you have done considerable damage.

In fact, the concept of the null pointer is frequently used as a way of indicating a problem--for instance,
some functions left over from C return 0 if they cannot correctly allocate memory (notably, the malloc
function). You want to be sure to handle this correctly if you ever use malloc or other C functions that
return a "NULL pointer" on failure.

In C++, if a call to new fails because the system is out of memory, then it will "throw an exception". For
the time being, you need not worry too much about this case, but you can read more about what
happens when new fails.
Taking Stock of Pointers
Pointers may feel like a very confusing topic at first but I think anyone can come to appreciate and
understand them. If you didn't feel like you absorbed everything about them, just take a few deep
breaths and re-read the lesson. You shouldn't feel like you've fully grasped every nuance of when and
why you need to use pointers, though you should have some idea of some of their basic uses.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 119 of 166


Object-Oriented Programming Concepts and C++ References

Session 5: Function Overloading

C++ function overloading programs

Source http://www.programmingsimplified.com/cpp/source-code/cpp-function-
overloading-example-program
Date of 14/05/2015
Retrieval

Function overloading in C++: C++ program for function overloading. Function overloading means two or
more functions can have the same name but either the number of arguments or the data type of
arguments has to be different. Return type has no role because function will return a value when it is
called and at compile time compiler will not be able to determine which function to call. In the first
example in our code we make two functions one for adding two integers and other for adding two floats
but they have same name and in the second program we make two functions with identical names but
pass them different number of arguments. Function overloading is also known as compile time
polymorphism.

C++ programming code


#include <iostream>

using namespace std;

/* Function arguments are of different data type */

long add(long, long);


float add(float, float);

int main()
{
long a, b, x;
float c, d, y;

cout << "Enter two integers\n";


cin >> a >> b;

x = add(a, b);

cout << "Sum of integers: " << x << endl;

cout << "Enter two floating point numbers\n";


cin >> c >> d;

y = add(c, d);

cout << "Sum of floats: " << y << endl;

return 0;
}

© Aptech Ltd. Version 1.0 Page 120 of 166


Object-Oriented Programming Concepts and C++ References

long add(long x, long y)


{
long sum;

sum = x + y;

return sum;
}

float add(float x, float y)


{
float sum;

sum = x + y;

return sum;
}

In the above program, we have created two functions "add" for two different data types you can create
more than two functions with same name according to requirement but making sure that compiler will be
able to determine which one to call. For example you can create add function for integers, doubles and
other data types in above program. In these functions you can see the code of functions is same except
data type, C++ provides a solution to this problem we can create a single function for different data types
which reduces code size which is via templates.

C++ programming code for function overloading


#include <iostream>

using namespace std;

/* Number of arguments are different */

void display(char []); // print the string passed as argument


void display(char [], char []);

int main()
{
char first[] = "C programming";
char second[] = "C++ programming";

display(first);
display(first, second);

return 0;
}

void display(char s[])


{
cout << s << endl;
}

void display(char s[], char t[])


{
cout << s << endl << t << endl;
}

© Aptech Ltd. Version 1.0 Page 121 of 166


Object-Oriented Programming Concepts and C++ References

Output of program:

C programming
C programming
C++ programming

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 122 of 166


Object-Oriented Programming Concepts and C++ References

C++ Operator Overloading Guidelines


Source http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html

Date of 14/05/2015
Retrieval

One of the nice features of C++ is that you can give special meanings to operators, when they are used
with user-defined classes. This is called operator overloading. You can implement C++ operator
overloads by providing special member-functions on your classes that follow a particular naming
convention. For example, to overload the + operator for your class, you would provide a member-function
named operator+ on your class.

The following set of operators is commonly overloaded for user-defined classes:

• = (assignment operator)
• + - * (binary arithmetic operators)
• += -= *= (compound assignment operators)
• == != (comparison operators)

Here are some guidelines for implementing these operators. These guidelines are very important to
follow, so definitely get in the habit early.

Assignment Operator =

The assignment operator has a signature like this:

class MyClass {
public:
...
MyClass & operator=(const MyClass &rhs);
...
}

MyClass a, b;
...
b = a; // Same as b.operator=(a);

Notice that the = operator takes a const-reference to the right hand side of the assignment. The reason
for this should be obvious, since we don't want to change that value; we only want to change what's on
the left hand side.

Also, you will notice that a reference is returned by the assignment operator. This is to allow operator
chaining. You typically see it with primitive types, like this:

int a, b, c, d, e;

a = b = c = d = e = 42;
This is interpreted by the compiler as:

© Aptech Ltd. Version 1.0 Page 123 of 166


Object-Oriented Programming Concepts and C++ References

a = (b = (c = (d = (e = 42))));
In other words, assignment is right-associative. The last assignment operation is evaluated first, and is
propagated leftward through the series of assignments. Specifically:

• e = 42 assigns 42 to e, then returns e as the result


• The value of e is then assigned to d, and then d is returned as the result
• The value of d is then assigned to c, and then c is returned as the result
• etc.

Now, in order to support operator chaining, the assignment operator must return some value. The value
that should be returned is a reference to the left-hand side of the assignment.

Notice that the returned reference is not declared const. This can be a bit confusing, because it allows
you to write crazy stuff like this:

MyClass a, b, c;
...
(a = b) = c; // What??
At first glance, you might want to prevent situations like this, by having operator = return a const
reference. However, statements like this will work with primitive types. And, even worse, some tools
actually rely on this behavior. Therefore, it is important to return a non-const reference from your
operator =. The rule of thumb is, "If it's good enough for ints, it's good enough for user-defined data-
types."

So, for the hypothetical MyClass assignment operator, you would do something like this:

// Take a const-reference to the right-hand side of the assignment.


// Return a non-const reference to the left-hand side.
MyClass& MyClass::operator=(const MyClass &rhs) {
... // Do the assignment operation!

return *this; // Return a reference to myself.


}
Remember, this is a pointer to the object that the member function is being called on. Since a = b is
treated as a.operator=(b), you can see why it makes sense to return the object that the function is called
on; object a is the left-hand side.

But, the member function needs to return a reference to the object, not a pointer to the object. So, it
returns *this, which returns what this points at (i.e. the object), not the pointer itself. (In C++,
instances are turned into references, and vice versa, pretty much automatically, so even though *this is
an instance, C++ implicitly converts it into a reference to the instance.)

Now, one more very important point about the assignment operator:

YOU MUST CHECK FOR SELF-ASSIGNMENT!

This is especially important when your class does its own memory allocation. Here is why: The typical
sequence of operations within an assignment operator is usually something like this:

MyClass& MyClass::operator=(const MyClass &rhs) {


// 1. Deallocate any memory that MyClass is using internally
// 2. Allocate some memory to hold the contents of rhs
// 3. Copy the values from rhs into this instance

© Aptech Ltd. Version 1.0 Page 124 of 166


Object-Oriented Programming Concepts and C++ References

// 4. Return *this
}
Now, what happens when you do something like this:
MyClass mc;
...
mc = mc; // BLAMMO.
You can hopefully see that this would wreak havoc on your program. Because mc is on the left-hand side
and on the right-hand side, the first thing that happens is that mc releases any memory it holds internally.
But, this is where the values were going to be copied from, since mc is also on the right-hand side! So,
you can see that this completely messes up the rest of the assignment operator's internals.

The easy way to avoid this is to CHECK FOR SELF-ASSIGNMENT. There are many ways to answer the
question, "Are these two instances the same?" But, for our purposes, just compare the two objects'
addresses. If they are the same, then don't do assignment. If they are different, then do the assignment.

So, the correct and safe version of the MyClass assignment operator would be this:

MyClass& MyClass::operator=(const MyClass &rhs) {


// Check for self-assignment!
if (this == &rhs) // Same object?
return *this; // Yes, so skip assignment, and just return *this.

... // Deallocate, allocate new space, copy values...

return *this;
}
Or, you can simplify this a bit by doing:
MyClass& MyClass::operator=(const MyClass &rhs) {

// Only do assignment if RHS is a different object from this.


if (this != &rhs) {
... // Deallocate, allocate new space, copy values...
}

return *this;
}
Remember that in the comparison, this is a pointer to the object being called, and &rhs is a pointer to
the object being passed in as the argument. So, you can see that we avoid the dangers of self-
assignment with this check.

In summary, the guidelines for the assignment operator are:

1. Take a const-reference for the argument (the right-hand side of the assignment).
2. Return a reference to the left-hand side, to support safe and reasonable operator chaining. (Do
this by returning *this.)
3. Check for self-assignment, by comparing the pointers (this to &rhs).

Compound Assignment Operators += -= *=

I discuss these before the arithmetic operators for a very specific reason, but we will get to that in a
moment. The important point is that these are destructive operators, because they update or replace the
values on the left-hand side of the assignment. So, you write:

© Aptech Ltd. Version 1.0 Page 125 of 166


Object-Oriented Programming Concepts and C++ References

MyClass a, b;
...
a += b; // Same as a.operator+=(b)
In this case, the values within a are modified by the += operator.

How those values are modified isn't very important - obviously, what MyClass represents will dictate
what these operators mean.

The member function signature for such an operator should be like this:

MyClass & MyClass::operator+=(const MyClass &rhs) {


...
}
We have already covered the reason why rhs is a const-reference. And, the implementation of such an
operation should also be straightforward.

But, you will notice that the operator returns a MyClass-reference, and a non-const one at that. This is so
you can do things like this:

MyClass mc;
...
(mc += 5) += 3;

Don't ask me why somebody would want to do this, but just like the normal assignment operator, this is
allowed by the primitive data types. Our user-defined datatypes should match the same general
characteristics of the primitive data types when it comes to operators, to make sure that everything works
as expected.

This is very straightforward to do. Just write your compound assignment operator implementation, and
return *this at the end, just like for the regular assignment operator. So, you would end up with
something like this:

MyClass & MyClass::operator+=(const MyClass &rhs) {


... // Do the compound assignment work.

return *this;
}

As one last note, in general you should beware of self-assignment with compound assignment operators
as well. Fortunately, none of the C++ track's labs require you to worry about this, but you should always
give it some thought when you are working on your own classes.

Binary Arithmetic Operators + - *

The binary arithmetic operators are interesting because they don't modify either operand - they actually
return a new value from the two arguments. You might think this is going to be an annoying bit of extra
work, but here is the secret:

Define your binary arithmetic operators using your compound assignment operators.

So, you have implemented your += operator, and now you want to implement the + operator. The function
signature should be like this:

© Aptech Ltd. Version 1.0 Page 126 of 166


Object-Oriented Programming Concepts and C++ References

// Add this instance's value to other, and return a new instance


// with the result.
const MyClass MyClass::operator+(const MyClass &other) const {
MyClass result = *this; // Make a copy of myself. Same as MyClass
result(*this);
result += other; // Use += to add other to the copy.
return result; // All done!
}
Simple!

Actually, this explicitly spells out all of the steps, and if you want, you can combine them all into a single
statement, like so:

// Add this instance's value to other, and return a new instance


// with the result.
const MyClass MyClass::operator+(const MyClass &other) const {
return MyClass(*this) += other;
}
This creates an unnamed instance of MyClass, which is a copy of *this. Then, the += operator is
called on the temporary value, and then returns it.

If that last statement doesn't make sense to you yet, then stick with the other way, which spells out all of
the steps. But, if you understand exactly what is going on, then you can use that approach.

You will notice that the + operator returns a const instance, not a const reference. This is so that
people can't write strange statements like this:

MyClass a, b, c;
...
(a + b) = c; // Wuh...?
This statement would basically do nothing, but if the + operator returns a non-const value,
it will compile! So, we want to return a const instance, so that such madness will not even
be allowed to compile.

To summarize, the guidelines for the binary arithmetic operators are:

1. Implement the compound assignment operators from scratch, and then define the binary
arithmetic operators in terms of the corresponding compound assignment operators.
2. Return a const instance, to prevent worthless and confusing assignment operations that
shouldn't be allowed.

Comparison Operators == and !=

The comparison operators are very simple. Define == first, using a function signature like this:

bool MyClass::operator==(const MyClass &other) const {


... // Compare the values, and return a bool result.
}
The internals are very obvious and straightforward, and the bool return-value is also very obvious.

The important point here is that the != operator can also be defined in terms of the == operator, and you
should do this to save effort. You can do something like this:

© Aptech Ltd. Version 1.0 Page 127 of 166


Object-Oriented Programming Concepts and C++ References

bool MyClass::operator!=(const MyClass &other) const {


return !(*this == other);
}
That way you get to reuse the hard work you did on implementing your == operator. Also, your code is far
less likely to exhibit inconsistencies between == and !=, since one is implemented in terms of the other.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 128 of 166


Object-Oriented Programming Concepts and C++ References

Session 6: Inheritance

Inheritance (object-oriented programming)

Source http://en.wikipedia.org/wiki/Inheritance_%28object-
oriented_programming%29
Date of 14/05/2015
Retrieval

In object-oriented programming (OOP), inheritance is when an object or class is based on another object
or class, using the same implementation (inheriting from a class) specifying implementation to maintain
the same behavior (realizing an interface; inheriting behavior). It is a mechanism for code reuse and to
allow independent extensions of the original software via public classes and interfaces. The relationships
of objects or classes through inheritance give rise to a hierarchy. Inheritance was invented in 1967 for
Simula.

Inheritance should not be confused with subtyping. In some languages inheritance and subtyping agree,
while in others they differ; in general subtyping establishes an is-a relationship, while inheritance only
reuses implementation and establishes a syntactic relationship, not necessarily a semantic relationship
(inheritance does not ensure behavioral subtyping). To distinguish these concepts, subtyping is also
known as interface inheritance, while inheritance as defined here is known as implementation
inheritance or code inheritance.

Inheritance is contrasted with object composition, where one object contains another object (or objects of
one class contain objects of another class); see composition over inheritance. Composition implements a
has-a relationship, in contrast to the is-a relationship of subtyping.

Types of inheritance

There are various types of inheritance, based on paradigm and specific language.

• Single Inheritance :

Single inheritance
In single inheritance, subclasses inherit the features of a single super class. A class acquires the
properties of another class.

© Aptech Ltd. Version 1.0 Page 129 of 166


Object-Oriented Programming Concepts and C++ References

Multiple Inheritance:

• Multiple Inheritance

Multiple Inheritance allows a class to have more than one super class and to inherit features from
all parent class.

"Multiple Inheritance (object-oriented programming) was widely supposed to be very difficult to implement
efficiently. For example, in a summary of C++ in his book on objective C Brd.Cox actually claimed that
adding Multiple inheritance to C++ was impossible. Thus, multiple inheritance seemed more of a
challenge. Since I had considered multiple inheritance as early as 1982 and found a simple and efficient
implementation technique in 1984. I couldn't resist the challenge. I suspect this to be the only case in
which fashion affected the sequence of events.”

— Bjarne Stroustrup

• Multilevel Inheritance: In multilevel inheritance a subclass is inherited from another subclass. It


is not uncommon that a class is derived from another derived class as shown in the figure
"Multilevel Inheritance".

• Multilevel Inheritance

The class A serves as a base class for the derived class B, which in turn serves as a base class
for the derived class C. The class B is known as intermediate base class since it provides a link
for the inheritance between A and C. The chain ABC is known as inheritance path.

A derived class with multilevel inheritance is declared as follows:

© Aptech Ltd. Version 1.0 Page 130 of 166


Object-Oriented Programming Concepts and C++ References

Class A(...); //Base class


Class B : public A(...); //B derived from A
Class C : public B(...); //C derived from B

This process can be extended to any number of levels.

• Hierarchical Inheritance : In hierarchical inheritance a single class serves as a superclass (base


class) for more than one sub class.
• Hybrid Inheritance : It is a mixture of all the above types of inheritance.

Subclasses and superclasses

A Subclass, "derived class", heir class, or child class is a modular, derivative class that inherits one or
more language entities from one or more other classes (called superclasses, base classes, or parent
classes). The semantics of class inheritance vary from language to language, but commonly the subclass
automatically inherits the instance variables and member functions of its superclasses. The general form
of defining a derived class is:

class derived-class-name : visibility-mode base-class-name


{
.....//
.....// members of derived class
.....//
};

• The colon indicates that the derived-class-name is derived from the base-class-name. The
visibility-mode is optional and, if present, may be either private or public. The default visibility-
mode is private. Visibility mode specifies whether the features of the base class are privately
derived or publicly derived.

Some languages support the inheritance of other construct as well. For example, in Eiffel, contracts which
define the specification of a class are also inherited by heirs. The superclass establishes a common
interface and foundational functionality, which specialized subclasses can inherit, modify, and
supplement. The software inherited by a subclass is considered reused in the subclass. A reference to an
instance of a class may actually be referring to one of its subclasses. The actual class of the object being
referenced is impossible to predict at compile-time. A uniform interface is used to invoke the member
functions of objects of a number of different classes. Subclass may replace superclass functions with
entirely new functions that must share the same method signature.

Uninheritable classes

In some languages a class may be declared as uninheritable by adding certain class modifiers to the
class declaration. Examples include the "final" keyword in Java or the "sealed" keyword in C#. Such
modifiers are added to the class declaration before the "class" keyword and the class identifier
declaration. Such sealed classes restrict reusability, particularly when developers only have access to
precompiled binaries and not source code.

The sealed class has no subclasses, so it can be easily deduced at compile time that references or
pointers to objects of that class are actually referencing instances of that class and not instances of
subclasses (they don't exist) or instances of superclasses (upcasting a reference type violates the type
system). subtype polymorphism. Because the exact type of the object being referenced is known before

© Aptech Ltd. Version 1.0 Page 131 of 166


Object-Oriented Programming Concepts and C++ References

execution, early binding (or "static dispatch") can be used instead of late binding (also called "dynamic
dispatch" or "dynamic binding") which requires one or more virtual method table lookups depending on
whether multiple inheritance or only single inheritance are supported in the programming language that is
being used.

Methods that cannot be overridden

Just as classes may be sealed/finalized method declarations may contain method modifiers that prevent
the method from being overridden (i.e. replaced with a new function with the same name and type
signature in a subclass). A private method is unoverridable simply because it is not accessible by classes
other than the class it is a member function of (this is not true for C++, though). A "final" method in Java, a
"sealed" method in C# or a frozen feature in Eiffel cannot be overridden.

Virtual methods

If the superclass method is a virtual method, then invocations of the superclass method will be
dynamically dispatched. Some languages require methods to be specifically declared as virtual (e.g. C++)
and in others all methods are virtual (e.g. Java). An invocation of a non-virtual method will always be
statically dispatched (i.e. the address of the function call is determined at compile-time). Static dispatch is
faster than dynamic dispatch and allows optimisations such as inline expansion.

Visibility of Inherited Members


Base class visibility Derived Class visibility

Public Derivation Private Derivation Protected Derivation


• Private → • Not inherited • Not inherited • Not inherited
• Protected → • Protected • Private • Protected
• Public → • Public • Private • Protected

Applications

Inheritance is used to co-relate two or more classes to each other.

• Overriding

Many object-oriented programming languages permit a class or object to replace the implementation of
an aspect—typically a behavior—that it has inherited. This process is usually called overriding. Overriding
introduces a complication: which version of the behavior does an instance of the inherited class use—the
one that is part of its own class, or the one from the parent (base) class? The answer varies between
programming languages, and some languages provide the ability to indicate that a particular behavior is
not to be overridden and should behave as defined by the base class. For instance, in C#, the base
method or property can only be overridden in a subclass if it is marked with the virtual, abstract, or
override modifier.] An alternative to overriding is hiding the inherited code.

• Code reuse

© Aptech Ltd. Version 1.0 Page 132 of 166


Object-Oriented Programming Concepts and C++ References

Implementation inheritance is the mechanism whereby a subclass re-uses code in a base class. By
default the subclass retains all of the operations of the base class, but the subclass may override some or
all operations, replacing the base-class implementation with its own.

In the following Python example, the subclass CubeSumComputer overrides the transform() method
of the base class SquareSumComputer. The base class comprises operations to compute the sum of
the squares between two integers. The subclass re-uses all of the functionality of the base class with the
exception of the operation that transforms a number into its square, replacing it with an operation that
transforms a number into its cube. The subclass therefore computes the sum of the cubes between two
integers.

class SquareSumComputer(object):
def __init__(self, a, b):
self.a = a
self.b = b

def transform(self, x):


return x * x

def inputs(self):
return range(self.a, self.b)

def compute(self):
return sum(self.transform(value) for value in self.inputs())

class CubeSumComputer(SquareSumComputer):
def transform(self, x):
return x * x * x

In most quarters, class inheritance for the sole purpose of code reuse has fallen out of favor.The primary
concern is that implementation inheritance does not provide any assurance of polymorphic
substitutability—an instance of the reusing class cannot necessarily be substituted for an instance of the
inherited class. An alternative technique, delegation, requires more programming effort, but avoids the
substitutability issue.In C++ private inheritance can be used as a form of implementation inheritance
without substitutability. Whereas public inheritance represents an "is-a" relationship and delegation
represents a "has-a" relationship, private (and protected) inheritance can be thought of as an "is
implemented in terms of" relationship.

Another frequent use of inheritance is to guarantee that classes maintain a certain common interface; that
is, they implement the same methods. The parent class can be a combination of implemented operations
and operations that are to be implemented in the child classes. Often, there is no interface change
between the supertype and subtype- the child implements the behavior described instead of its parent
class.

Inheritance vs subtyping

Inheritance is similar to but distinct from subtyping. Subtyping enables a given type to be substituted for
another type or abstraction, and is said to establish an is-a relationship between the subtype and some
existing abstraction, either implicitly or explicitly, depending on language support. The relationship can be
expressed explicitly via inheritance in languages that support inheritance as a subtyping mechanism. For
example, the following C++ code establishes an explicit inheritance relationship between classes B and
A, where B is both a subclass and a subtype of A, and can be used as an A wherever a B is specified
(via a reference, a pointer or the object itself).

© Aptech Ltd. Version 1.0 Page 133 of 166


Object-Oriented Programming Concepts and C++ References

class A
{ public:
void DoSomethingALike() const {}
};

class B : public A
{ public:
void DoSomethingBLike() const {}
};

void UseAnA(A const& some_A)


{
some_A.DoSomethingALike();
}

void SomeFunc()
{
B b;
UseAnA(b); // b can be substituted for an A.
}

In programming languages that do not support inheritance as a subtyping mechanism, the relationship
between a base class and a derived class is only a relationship between implementations (a mechanism
for code reuse), as compared to a relationship between types. Inheritance, even in programming
languages that support inheritance as a subtyping mechanism, does not necessarily entail behavioral
subtyping. It is entirely possible to derive a class whose object will behave incorrectly when used in a
context where the parent class is expected; see the Liskov substitution principle. (Compare
connotation/denotation.) In some OOP languages, the notions of code reuse and subtyping coincide
because the only way to declare a subtype is to define a new class that inherits the implementation of
another.

Design constraints

Using inheritance extensively in designing a program imposes certain constraints.

For example, consider a class Person that contains a person's name, date of birth, address and phone
number. We can define a subclass of Person called Student that contains the person's grade point
average and classes taken, and another subclass of Person called Employee that contains the person's
job-title, employer, and salary.

In defining this inheritance hierarchy we have already defined certain restrictions, not all of which are
desirable:

• Singleness: using single inheritance, a subclass can inherit from only one superclass. Continuing
the example given above, Person can be either a Student or an Employee, but not both. Using
multiple inheritance partially solves this problem, as one can then define a StudentEmployee
class that inherits from both Student and Employee. However, in most implementations, it can still
inherit from each superclass only once, and thus, does not support cases in which a student has
two jobs or attends two institutions. The inheritance model available in Eiffel makes this possible
through support for repeated inheritance.

• Static: the inheritance hierarchy of an object is fixed at instantiation when the object's type is
selected and does not change with time. For example, the inheritance graph does not allow a
Student object to become a Employee object while retaining the state of its Person superclass.

© Aptech Ltd. Version 1.0 Page 134 of 166


Object-Oriented Programming Concepts and C++ References

(This kind of behavior, however, can be achieved with the decorator pattern.) Some have
criticized inheritance, contending that it locks developers into their original design standards.

• Visibility: whenever client code has access to an object, it generally has access to all the object's
superclass data. Even if the superclass has not been declared public, the client can still cast the
object to its superclass type. For example, there is no way to give a function a pointer to a
Student's grade point average and transcript without also giving that function access to all of the
personal data stored in the student's Person superclass. Many modern languages, including C++
and Java, provide a "protected" access modifier that allows subclasses to access the data,
without allowing any code outside the chain of inheritance to access it.

The composite reuse principle is an alternative to inheritance. This technique supports polymorphism and
code reuse by separating behaviors from the primary class hierarchy and including specific behavior
classes as required in any business domain class. This approach avoids the static nature of a class
hierarchy by allowing behavior modifications at run time and allows a single class to implement behaviors
buffet-style, instead of being restricted to the behaviors of its ancestor classes.

Issues and alternatives

Implementation inheritance is controversial among programmers and theoreticians of object-oriented


programming since at least the 1990s. Among them are the authors of Design Patterns, who advocate
interface inheritance instead, and favor composition over inheritance.

According to Allen Holub, the main problem with implementation inheritance is that it introduces
unnecessary coupling in the form of the "fragile base class problem" modifications to the base class
implementation can cause inadvertent behavioral changes in subclasses. Using interfaces avoids this
problem since no implementation is shared, only the API.Another way of stating this is that "inheritance
breaks encapsulation". The problem surfaces clearly in open object-oriented systems such as
frameworks, where client code is expected to inherit from system-supplied classes and then substituted
for the system's classes in its algorithms.

Reportedly, Java inventor James Gosling has spoken against implementation inheritance, stating that he
would not include it if he were to redesign Java.Language designs that decouple inheritance from
subtyping (interface inheritance) appeared as early as 1990 a modern example of this is the Go
programming language.

Complex inheritance, or inheritance used within an insufficiently mature design, may lead to the yo-yo
problem.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 135 of 166


Object-Oriented Programming Concepts and C++ References

Introduction to Inheritance in C++

Source https://www.cs.bu.edu/teaching/cpp/inheritance/intro/
Date of 14/05/2015
Retrieval

• Introduction:

Modern object-oriented (OO) languages provide 3 capabilities:

• encapsulation
• inheritance
• polymorphism

which can improve the design, structure and reusability of code.

Here, we'll explore how the object-oriented (OO) programming capability known as inheritance can be
used in C++.

• Employee example:

Real-world entities, like employees, are naturally described by both data and functionality.

We will represent different types of employees:

• a generic employee
• a manager
• a supervisor

For these employees, we'll store data, like their:

• name
• pay rate

And...we'll require some functionality, like being able to:

• initialize the employee


• get the employee's fields (e.g., name)
• calculate the employee's pay

Note: We don't care what the pay period for an employee is. They might receive pay weekly, bi-weekly,
monthly, etc. It is not important in this example.

• Employee class:

Object-oriented languages typically provide a natural way to treat data and functionality as a single entity.
In C++, we do so by creating a class.

© Aptech Ltd. Version 1.0 Page 136 of 166


Object-Oriented Programming Concepts and C++ References

Here is a class definition for a generic Employee:

class Employee {
public:
Employee(string theName, float thePayRate);

string getName() const;


float getPayRate() const;

float pay(float hoursWorked) const;

protected:
string name;
float payRate;
};

Note: For now, just think of the "protected" keyword as being like "private".

The class consists of:

• A constructor to initialize fields of the class.


• Methods to "get" the fields.
• A method to calculate the employee's pay (given the number of hours worked).

Definitions for each of the methods follow:

Employee::Employee(string theName, float thePayRate)


{
name = theName;
payRate = thePayRate;
}

string Employee::getName() const


{
return name;
}

float Employee::getPayRate() const


{
return payRate;
}

float Employee::pay(float hoursWorked) const


{
return hoursWorked * payRate;
}

Note that the payRate is used as an hourly wage.

The class would be used something like:


#include "employee.h"

© Aptech Ltd. Version 1.0 Page 137 of 166


Object-Oriented Programming Concepts and C++ References

...

Employee empl("John Burke", 25.0);

// Print out name and pay (based on 40 hours work).


cout << "Name: " << empl.getName() << endl;
cout << "Pay: " << empl.pay(40.0) << endl;
• Manager class:

In the real world, we don't view everything as unique; we often view something as being like something
else but with differences or additions.

Managers are like regular employees; however, there might be differences. For example, they might be
paid by a salary.

Note: Employees paid by a salary (i.e., those that are salaried) get a fixed amount of money each pay
period (e.g., week, 2 weeks, month) regardless of how many hours they work.

Our first attempt to write a class for a manager gives the following class definition:

class Manager {
public:
Manager(string theName,
float thePayRate,
bool isSalaried);

string getName() const;


float getPayRate() const;
bool getSalaried() const;

float pay(float hoursWorked) const;

protected:
string name;
float payRate;
bool salaried;
};
It mainly differs from Employee in that it has an additional field (salaried) and method
(getSalaried()).

The method definitions for class Manager do not differ much from Employee either:

Manager::Manager(string theName,
float thePayRate,
bool isSalaried)
{
name = theName;
payRate = thePayRate;
salaried = isSalaried;
}

© Aptech Ltd. Version 1.0 Page 138 of 166


Object-Oriented Programming Concepts and C++ References

string Manager::getName() const


{
return name;
}

float Manager::getPayRate() const


{
return payRate;
}

bool Manager::getSalaried() const


{
return salaried;
}

float Manager::pay(float hoursWorked) const


{
if (salaried)
return payRate;
/* else */
return hoursWorked * payRate;
}

They add very little new code to what was written in Employee.

Compared to Employee, in Manager...

• The methods getName() and getPayRate() are identical to those in


Employee.
• Method getSalaried() is new.
• The constructor and pay() method work differently. Nonetheless, they do some of
the same work as their counterparts in the Employee class.

Finally, the payRate has 2 possible uses in the Manager class...

float Manager::pay(float hoursWorked) const


{
if (salaried)
return payRate;
/* else */
return hoursWorked * payRate;
}
If the manager is salaried, payRate is the fixed rate for the pay period; otherwise, it
represents an hourly rate, just like it does for a regular employee.

Such a Manager can be used in a similar manner to an Employee:


#include "manager0.h"

...

Manager mgr("Jan Kovacs", 1200.0, true);

© Aptech Ltd. Version 1.0 Page 139 of 166


Object-Oriented Programming Concepts and C++ References

// Print out name and pay (based on 40 hours work).


cout << "Name: " << mgr.getName() << endl;
cout << "Pay: " << mgr.pay(40.0) << endl;
• Reuse:

We have done unnecessary work to create Manager, which is similar to (and really is a "kind of")
Employee.

We can fix this using the OO concept of inheritance. If we let a manager inherit from an employee, then it
will get all the data and functionality of an employee. We can then add any new data and methods
needed for a manager and redefine any methods that differ for a manager.

Here, we show a new implementation of Manager that inherits from Employee:

#include "employee.h"

class Manager : public Employee {


public:
Manager(string theName,
float thePayRate,
bool isSalaried);

bool getSalaried() const;

float pay(float hoursWorked) const;

protected:
bool salaried;
};

The line:

class Manager : public Employee {


causes Manager to inherit all the data and methods of Employee.

Note: Although other access specifiers (besides "public") can be used with inheritance, we
will only discuss public inheritance here.

The only things included in the class definition are:

• a constructor,
• the new field salaried,
• a way to access it with the method getSalaried(),
• and a declaration for pay() (which is redefined in Manager).

Like this new class definition, the method definitions are also simplified:

Manager::Manager(string theName,
float thePayRate,

© Aptech Ltd. Version 1.0 Page 140 of 166


Object-Oriented Programming Concepts and C++ References

bool isSalaried)
: Employee(theName, thePayRate)
{
salaried = isSalaried;
}

bool Manager::getSalaried() const


{
return salaried;
}

float Manager::pay(float hoursWorked) const


{
if (salaried)
return payRate;
/* else */
return Employee::pay(hoursWorked);
}
There are some things to note about these method definitions...

Member initialization list


For constructors that require arguments, you must write a new constructor for each class.

Note: Classes don't explicitly inherit constructors.

For the Manager class, we needed a constructor:

Manager::Manager(string theName,
float thePayRate,
bool isSalaried)
: Employee(theName, thePayRate)
{
salaried = isSalaried;
}

that does some of the same work as the Employee constructor. To do so, we reused Employee's
constructor.

The only way to pass values to Employee's constructor in this context is via a member initialization list.

A member initialization list follows a constructor's parameter list. It consists of a colon ( :) and a comma-
separated list of inherited class names (and values to be passed to their constructors).

Note: The member initialization list can also be used to pass values to constructors of data
members. For example,
class SomeClass {
public:
SomeClass();

private:

© Aptech Ltd. Version 1.0 Page 141 of 166


Object-Oriented Programming Concepts and C++ References

const int SIZE;


AnotherClass data;
};

SomeClass::SomeClass() : SIZE(10), data("foo")


{
// more initialization code
}

Without doing so, SIZE could not be initialized (because its constant) and data's default constructor (if
it has one) would be used.

The protected access specifier


Methods of Manager have access to payRate because it was declared in Employee as
"protected":
float Manager::pay(float hoursWorked) const
{
if (salaried)
return payRate; // Yeah, I can use!
...
}
I.e., classes that inherit a "protected" field or method can access them.

For those using an object (versus those defining a class), "protected" works like the "private" access
specifier:

Manager mgr;
mgr.payRate; // Doesn't work!
I.e., the "protected" fields remain inaccessible just as they were in Employee:
Employee empl;
empl.payRate; // Doesn't work!

Calling inherited methods


The pay() method of Manager uses a different calculation if the manager is salaried.
Otherwise, it makes the same calculation as a regular Employee:
float Manager::pay(float hoursWorked) const
{
if (salaried)
return payRate;
/* else */
return Employee::pay(hoursWorked);
}
We reused the pay() method of Employee to define the pay() method of Manager.

Note that when we call Employee's pay() method:

Employee::pay(hoursWorked);

© Aptech Ltd. Version 1.0 Page 142 of 166


Object-Oriented Programming Concepts and C++ References

we must explicitly specify the class from which it comes (i.e., from which it was inherited).
Without doing so, we'd have an infinite recursive call:
float Manager::pay(float hoursWorked) const
{
...
return pay(hoursWorked); // Calls Manager::pay()!
}

This new Manager class can be used just like our first attempt:
#include "manager.h"

...

Manager mgr("Jan Kovacs", 1200.0, true);

// Print out name and pay (based on 40 hours work).


cout << "Name: " << mgr.getName() << endl;
cout << "Pay: " << mgr.pay(40.0) << endl;
Excitingly, it has methods from Employee, like getName(), that we did not declare or
define in Manager...

Remember, it inherited all the data and methods of an Employee! Thus, we have reused our definition
of an employee to simplify defining a manager.

• Class Hierarchy:

Since we now have one class that inherits from another, we have the beginnings of a class hierarchy:

Employee
|
Manager
We say that Employee is the base class and Manager is a derived class of Employee.

Note: Alternatively, we may call Employee the superclass and Manager the subclass.

If needed, this hierarchy could be extended to include more classes.

Adding a Supervisor
To add another type of employee, such as a supervisor, a new class can be created. Two
choices of where to place a Supervisor class in the hierarchy are:
a) Employee b) Employee
| / \
Manager Manager Supervisor
|
Supervisor

© Aptech Ltd. Version 1.0 Page 143 of 166


Object-Oriented Programming Concepts and C++ References

a. A supervisor is a kind of manager.


TheSupervisor class directly inherits from Manager and indirectly inherits from
Employee.
b. A supervisor is just a special kind of employee.
Supervisor directly inherits from Employee.

Aside: We can say that Supervisor inherits from Employee when there is either a
direct or indirect inheritance relationship.

Which hierarchy would we choose?

If a supervisor is viewed as part of management, then choice a) is probably your answer. Nonetheless,
this is a decision not to be taken lightly. How one designs the inheritance hierarchy greatly affects what
you can do with those classes later.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 144 of 166


Object-Oriented Programming Concepts and C++ References

Session 7: Multiple Inheritance and Polymorphism


Introduction to Polymorphism in C++
Source https://www.cs.bu.edu/teaching/cpp/polymorphism/intro/
Date of 14/05/2015
Retrieval

Introduction:

Modern object-oriented (OO) languages provide 3 capabilities:

• encapsulation
• inheritance
• polymorphism

which can improve the design, structure and reusability of code.

Here, we'll explore how the programming capability known as polymorphism can be used in C++.

Note: You should already have some understanding of the first two concepts before attempting this
material.

• What is polymorphism?

In programming languages, polymorphism means that some code or operations or objects behave
differently in different contexts.

For example, the + (plus) operator in C++:

4 + 5 <-- integer addition


3.14 + 2.0 <-- floating point addition
s1 + "bar" <-- string concatenation!

In C++, that type of polymorphism is called overloading.

Typically, when the term polymorphism is used with C++, however, it refers to using virtual methods,
which we'll discuss shortly.

• Employee example:

Here, we will represent 2 types of employees as classes in C++:

• a generic employee (class Employee)


• a manager (class Manager)

For these employees, we'll store data, like their:

© Aptech Ltd. Version 1.0 Page 145 of 166


Object-Oriented Programming Concepts and C++ References

• name
• pay rate

And...we'll require some functionality, like being able to:

• initialize the employee


• get the employee's fields
• calculate the employee's pay

To help demonstrate polymorphism in C++, we'll focus on the methods that calculate an employee's pay.

Employee class:

Here is a class definition for a generic Employee:

class Employee {
public:
Employee(string theName, float thePayRate);

string getName() const;


float getPayRate() const;

float pay(float hoursWorked) const;

protected:
string name;
float payRate;
};

Definitions for each of the methods follow:

Employee::Employee(string theName, float thePayRate)


{
name = theName;
payRate = thePayRate;
}

string Employee::getName() const


{
return name;
}

float Employee::getPayRate() const


{
return payRate;
}

float Employee::pay(float hoursWorked) const


{
return hoursWorked * payRate;
}

Note that the payRate is used as an hourly wage.

© Aptech Ltd. Version 1.0 Page 146 of 166


Object-Oriented Programming Concepts and C++ References

• Manager class:

We'll also have a Manager class that is defined reusing the Employee class (i.e., via inheritance).

Remember, if a manager inherits from an employee, then it will get all the data and functionality of an
employee. We can then add any new data and methods needed for a manager and override (i.e.,
redefine) any methods that differ for a manager.

Here is the class definition for a Manager:

#include "employee.h"

class Manager : public Employee {


public:
Manager(string theName,
float thePayRate,
bool isSalaried);

bool getSalaried() const;

float pay(float hoursWorked) const;

protected:
bool salaried;
};

Definitions for the additional or overridden methods follow:

Manager::Manager(string theName,
float thePayRate,
bool isSalaried)
: Employee(theName, thePayRate)
{
salaried = isSalaried;
}

bool Manager::getSalaried() const


{
return salaried;
}

float Manager::pay(float hoursWorked) const


{
if (salaried)
return payRate;
/* else */
return Employee::pay(hoursWorked);
}
The pay() method is given a new definition, in which the payRate has 2 possible uses. If the manager
is salaried, payRate is the fixed rate for the pay period; otherwise, it represents an hourly rate, just like it
does for a regular employee.

Note: Employees paid by a salary (i.e., those that are salaried) get a fixed amount of money each pay
period (e.g., week, 2 weeks, month) regardless of how many hours they work.

© Aptech Ltd. Version 1.0 Page 147 of 166


Object-Oriented Programming Concepts and C++ References

Using Employee and Manager objects

These Employee and Manager classes can be used as follows:

#include "employee.h"
#include "manager.h"

...

// Print out name and pay (based on 40 hours work).

Employee empl("John Burke", 25.0);

cout << "Name: " << empl.getName() << endl;


cout << "Pay: " << empl.pay(40.0) << endl;

Manager mgr("Jan Kovacs", 1200.0, true);

cout << "Name: " << mgr.getName() << endl;


cout << "Pay: " << mgr.pay(40.0) << endl;
cout << "Salaried: " << mgr.getSalaried() << endl;

Recall that a Manager has all the methods inherited from Employee, like getName(), new versions for
those it overrode, like pay(), plus ones it added, like getSalaried().

Why public inheritance:

Often, we want a derived class that is a "kind of" the base class:

Employee <-- generic employee


|
Manager <-- specific kind of employee,
but still an "employee"
In these cases, public inheritance:
class Manager : public Employee {
is the kind of inheritance that should be used.

I.e, if a Manager is truly a "kind of" Employee, then it should have all the things (i.e., the same interface)
that an Employee has.

Deriving a class publicly guarantees this, as all the public data and methods from the base class remain
public in the derived class.

Note: Everything that was protected in the base class remains protected in the derived class. And, those
things that were private in the base class are not directly accessible in the derived class.

There is also private and protected inheritance, but they do not imply the same kind of reuse as public
inheritance. With private and protected inheritance, we cannot say that the derived class is a "kind of" the
base class, since the interface the base class guarantees (i.e., its public parts) becomes private or

© Aptech Ltd. Version 1.0 Page 148 of 166


Object-Oriented Programming Concepts and C++ References

protected, respectively. Thus, private and protected inheritance represent a different way of reusing a
class.

As we'll see, public inheritance makes writing generic code easier.

Pointer to a base class

A base class pointer can point to either an object of the base class or of any publicly-derived class:

Employee *emplP;

if (condition1) {
emplP = new Employee(...);
} else if (condition2) {
emplP = new Manager(...);
}
This allows us, for example, to write one set of code to deal with any kind of employee:
cout << "Name: " << emplP->getName();
cout << "Pay rate: " << emplP->getPayRate();

Note: Typically, one just needs to write different code only to assign the pointer to the right kind of object,
but not to call methods (as above).

Calling methods with base class pointers:

As you may suspect, calling getName() or getPayRate() using an Employee pointer:

cout << "Name: " << emplP->getName();


cout << "Pay rate: " << emplP->getPayRate();
will do the same things (return the name field or payRate field) whether the pointer points to an
Employee or Manager.

That's because both classes use the exact same version of those methods--the one defined in Employee.

What, however, will happen when a method that was overridden is called?

Employee *emplP;

if (condition1) {
emplP = new Employee(...);
} else if (condition2) {
emplP = new Manager(...);
}

cout << "Pay: " << emplP->pay(40.0);

Your first thought may be that the same thing that would happen with actual Employee and Manager
objects would happen:

Employee empl;
Manager mgr;

© Aptech Ltd. Version 1.0 Page 149 of 166


Object-Oriented Programming Concepts and C++ References

cout << "Pay: " << empl.pay(40.0); // calls Employee::pay()


cout << "Pay: " << mgr.pay(40.0); // calls Manager::pay()

In fact, that is not the case:

Employee *emplP;

emplP = &empl; // make point to an Employee


cout << "Pay: " << emplP->pay(40.0); // calls Employee::pay()

emplP = &mgr; // make point to a Manager


cout << "Pay: " << emplP->pay(40.0); // calls Employee::pay()

By default, it is the type of the pointer (i.e., Employee), not the type of the object it points to (i.e., possibly
Manager) that determines which version will be called:

Employee *emplP;

if (condition1) {
emplP = new Employee(...);
} else if (condition2) {
emplP = new Manager(...);
}

cout << "Pay: " << emplP->pay(40.0); // calls Employee::pay()


We'd prefer that it call the version of pay() that corresponds to the type of the object pointed to:
Employee *emplP;

emplP = &empl; // make point to an Employee


cout << "Pay: " << emplP->pay(40.0); // call Employee::pay()

emplP = &mgr; // make point to a Manager


cout << "Pay: " << emplP->pay(40.0); // please--Manager::pay()?
We can get that behavior by making the pay() method virtual! We do so in its declaration:
class Employee {
public:
...
virtual float pay(float hoursWorked) const;
...
};

Note: Once a method is declared as virtual, it is virtual in all derived classes too. We prefer to explicitly
label it as virtual in derived classes as a reminder:
class Manager : public Employee {
public:
...
virtual float pay(float hoursWorked) const;
...
};

virtual methods with references:

The same behavior that virtual methods exhibit with pointers to objects extends to references.

© Aptech Ltd. Version 1.0 Page 150 of 166


Object-Oriented Programming Concepts and C++ References

For example, suppose we wanted a function to print the pay for any kind of employee. If the pay()
method was not virtual, we'd have to do something like:

typedef enum {EMPL_PLAIN, EMPL_MANAGER} KindOfEmployee;

void PrintPay0(const Employee &empl,


KindOfEmployee kind,
float hoursWorked)
{
float amount;

switch (kind) {
case EMPL_PLAIN:
amount = empl.pay(hoursWorked);
break;
case EMPL_MANAGER:
// convert to Manager...
const Manager &mgr = static_cast<const Manager &>(empl);
// ...then call its pay()
amount = mgr.pay(hoursWorked);
break;
}

cout << "Pay: " << amount << endl;


}

Every time a new type of employee is added, we must add another case with a nasty cast (and another
value in the enumeration).

Function PrintPay0() can be used as:


Employee empl;
Manager mgr;

PrintPay0(empl, EMPL_PLAIN, 40.0);


PrintPay0(mgr, EMPL_MANAGER, 40.0);

If the pay() method is declared virtual, the function can be written much simpler:

void PrintPay(const Employee &empl,


float hoursWorked)
{
cout << "Pay: " << empl.pay(hoursWorked) << endl;
}

If a new class that inherits (publicly) from Employee is later added, then PrintPay() works for it too
(without modification).

Function PrintPay() can be used as:


Employee empl;
Manager mgr;

© Aptech Ltd. Version 1.0 Page 151 of 166


Object-Oriented Programming Concepts and C++ References

PrintPay(empl, 40.0);
PrintPay(mgr, 40.0);

Calling virtual methods within other methods:

The polymorphic behavior of virtual methods extends to calling them within another method.

For example, suppose the pay() method has been declared virtual in Employee.

And, we add a printPay() method to the Employee class:

void Employee::printPay(float hoursWorked) const


{
cout << "Pay: " << pay(hoursWorked) << endl;
}

which gets inherited in Manager without being overridden.

Which version of pay() will be called within printPay() for a Manager?

Manager mgr;
mgr.printPay(40.0);

The Manager version of pay() gets called inside of printPay() even though printPay() was only
defined in Employee!

Why? Remember that:

void Employee::printPay(float hoursWorked) const


{
... pay(hoursWorked) ...
}
is really shorthand for:
void Employee::printPay(float hoursWorked) const
{
... this->pay(hoursWorked) ...
}
and we know that virtual functions behave polymorphically with pointers!
Design issues:

We can often write better code using polymorphism, i.e., using public inheritance, base class pointers (or
references), and virtual functions.

For example, we were able to write generic code to print any employee's pay:

void PrintPay(const Employee &empl,


float hoursWorked)
{
cout << "Pay: " << empl.pay(hoursWorked) << endl;
}
That makes sense, since pay is printed the same for all employees.

© Aptech Ltd. Version 1.0 Page 152 of 166


Object-Oriented Programming Concepts and C++ References

The differences are only in how pay is calculated, and we were able to isolate those where they belong, in
the different classes:

virtual float Employee::pay(float hoursWorked) const;

virtual float Manager::pay(float hoursWorked) const;

Nonetheless, using polymorphism to produce good designs takes thought.

For example, suppose we add a new kind of employee, a Supervisor, with one of the following two
choices of where to place the new class in the hierarchy:

a) Employee b) Employee
| / \
Manager Manager Supervisor
|
Supervisor

If we later write a function that takes a Manager reference:

void GiveRaise(Manager &mgr);

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 153 of 166


Object-Oriented Programming Concepts and C++ References

Polymorphism

Source http://sfb649.wiwi.hu-
berlin.de/fedc_homepage/xplore/ebooks/html/csa/node113.html
Date of 14/05/2015
Retrieval

At the end of the previous section, we have seen that instances of many different classes were dealt with
in the same way. We did not know the exact type of the instances stored in the store container; it was
sufficient that they were instances of any class derived from the Particle class.

This feature of the OOP is called polymorphism. Polymorphism means that instances of various classes
may be used in the same way - they accept the same messages, so their methods may be called without
any regard to the exact type of the instance. In some programming languages (e.g., in Java), this is
automatic behavior of the objects (or of their methods), in some programming languages (e.g. in C++) this
behavior must be explicitly declared.

There are at least two ways to achieve polymorphic behavior: The use of the inheritance and the use of
the interfaces.

Example Let's consider once again the example given at the end of the ''Inheritance'' section. The
expression store[i] is of type ''pointer to the Particle class'', even though it in fact points to an instance of
the Electron, Photon, or some other derived class.

It follows that the statement

store[i] -> Interact(det); // Which method is called?


might be interpreted as the call of the Particle::Interact() method, even though it should be interpreted as
the call of the Interact() method of some derived class.

Early and Late Binding

The previous example shows that there are two possible approaches to the resolution of the type of the
instance for which the method is called, if the pointer (or reference) to the instance is used:

• Early binding. The type of the instance is determined in the compile time. It follows that the static
(declared) type of the pointer or reference is used. This is the default for all methods in C++, C ,
or Object Pascal.
• Late binding. The type of the instance is determined in the run time. It follows that the actual type
of the instance is used and the method of this type is called. This is always used for the methods
in Java. In C++, the virtual keyword denotes the methods using the late binding.

Late binding gives the class polymorphic behavior. On the other hand, late binding is less effective than
early binding, even though the difference may be negligible. (In C++ on PCs, the difference between the
late and the early binding is usually one machine instruction per method call.)

Any method that might be overridden in any of the derived classes should use the late binding.

© Aptech Ltd. Version 1.0 Page 154 of 166


Object-Oriented Programming Concepts and C++ References

Note:

In C++ and other OOP languages in which the late binding must be declared, the classes containing at
least one virtual method are called polymorphic classes. Classes without any virtual method are called
non-polymorphic classes. In languages like Java, where all the methods use late binding by default, all
the classes are polymorphic.

Implementation of the Late Binding

In this subsection, some low level concepts will be discussed. They are not necessary for understanding
the basic concepts of the OOP, but they can give better insight in it.

We will explore one the common way of implementation of the late binding, i.e., of the determination of
the actual type of the instance for which the method is called.

This is based on the so called virtual method tables. The virtual method table (VMT) is the hidden class
data member that is part of any polymorphic class. Any polymorphic class contains exactly one VMT.
(The hidden class member is a class member the programmer does not declare - the compiler adds it
automatically.)

The VMT is an array containing pointers to all the virtual methods of the class. Any derived class has its
own VMT that contains pointers to all the virtual methods (even those that are not overridden in this
class). The pointers to the virtual methods in the VMT of the derived class are in the same order as the
pointers to corresponding methods in the base class.

Any instance of the polymorphic class contains another hidden data member - the pointer to the VMT.
This data member is stored in all the instances at the same place - e.g. at the beginning.

The method call is performed in the following way:

1. The program takes the instance, for which the method is called.
2. In the instance, it finds the pointer to the VMT.
3. In the VMT, it finds the pointer to the method called. In all the VMTs this pointer is in the same
entry; e.g., the pointer to the Interact() method might be in the VMT of the Particle class and in
the VMTs of all the classes derived from the Particle in the first entry.
4. The program uses this pointer to call the method of the actual class of the instance.

Figure 7.1 illustrates this process for the Particle base class and two derived classes. The values
stored in the VMT are set usually at the start of the program or when the class is loaded to the memory.
The values of the pointer to the VMT in the instances are set automatically by the constructor.

© Aptech Ltd. Version 1.0 Page 155 of 166


Object-Oriented Programming Concepts and C++ References

Figure 7.1: Typical implementation of the late binding


Abstract Class

In some cases, the base class represents such an abstract concept that some operations with instances
of this class cannot be implemented. Nevertheless, at least the stub of the corresponding method should
be present in the class, because this class is used as a base class and determines the common interface
for all the derived classes.

In OOP such a class is called the abstract class and such an operation is called the abstract method.
Abstract methods have no implementation (no method body).

It is not allowed to create instances of the abstract classes and it is not allowed to call the abstract
methods. It is of course possible to define pointers or references to abstract classes.

The abstract classes serve as base classes. If the derived class does not implement any of the inherited
abstract methods, it will be abstract like the base class. The abstract class

• defines the interface of the derived classes,


• provides the implementation of non-polymorphic methods for the derived classes, and
• offers a default implementation of non-abstract polymorphic (virtual) methods.

Note that the abstract classes are italicized in the UML class diagrams - see e.g. the Particle class in
Figure 7.1

Example Consider the Particle class defined above. How could the Interact() method be
implemented?

© Aptech Ltd. Version 1.0 Page 156 of 166


Object-Oriented Programming Concepts and C++ References

For the derived classes, the situation is clear: If it is, e.g., the Photon, the interaction could be the
photoelectric effect, the Compton scattering, or some other interaction known to particle physicists;
probabilities of these phenomena are determined according to their total effective cross sections. For the
other derived classes, there are other well defined possibilities that can be expressed in the program
code.

However, there is no general interaction, that could be used to implement the Interact() method of the
general Particle. On the other hand, this method must be declared in the Particle class as the part
of the common interface of derived classes. If we omit it, the statement

store[i] -> Interact(det);


will not compile, because store[i] is the pointer to the Particle class that does not
contain such a method.

So, the Interact() method should be declared as abstract (in C++, the abstract methods are called
pure virtual methods). In the following revision of the Particle class, we omit all other parts of that class
that are unchanged.

// Particle as an abstract class


class Particle
{
public:
// Pure virtual method
virtual void Interact(Detector *aDetector) = 0;
// All other public members as before
protected:
// All data members as before
};

Interfaces

The interface may be defined as a named set of methods and constants. This set may be empty.

The interface represents a way to achieve the polymorphic behavior; it is an alternative to inheritance.
This concept is relatively new in OOP; it was first widely used in the Java language.

In languages that support interfaces, any class may declare that it implements the given interface. This
means that the class will supply the implementations (bodies) of the methods in the interface.

Note the terminological difference: Even though interfaces are syntactically similar to the classes that
contain only public abstract methods, they are not inherited, but they are implemented. In programming
languages, that support interfaces, any class may implement many interfaces, even if the language does
not support multiple inheritance.

The interface represents the type. If class C implements interfaces I1 and I2, any instance of this class
is an instance of type C and also an instance of type I1 and of type I2.

The interface is usually represented by a small circle connected to the class icon in the UML class

diagrams It may also be represented by a class-like icon marked by the interface label
(''stereotype''). Implementation of the interface is represented by a dashed arrow pointing to the
implementing class.

© Aptech Ltd. Version 1.0 Page 157 of 166


Object-Oriented Programming Concepts and C++ References

Interfaces in C++

As we have chosen C++ as the language of examples, it is necessary to cover briefly the interfaces in this
language. C++ does not support interfaces directly; nevertheless, interfaces may be fully simulated by
abstract classes that contain only public abstract (pure virtual) methods, and the interface implementation
may be substituted by the inheritance. This will be demonstrated by the following example.

Example The Monte Carlo simulation may be time-consuming and it would be convenient to have the
possibility to store the status of the simulation into a file, so that the computation might be interrupted and
continued later.

It is clear that all the generated but not yet processed particles should be stored. The status of the particle
source, and consequently the status of the random numbers generator, should be stored, too. This is
necessary especially for debugging, because it ensures that we could get the same sequence of random
number in repeated runs of the program, even if they are interrupted.

It follows that we have at least two different object types belonging to different class hierarchies that have
a common feature - they will be stored in a file and later will be restored into their original state. It follows
that all the classes involved should have suitable methods, e.g., store() and restore().

The simulated experiment is represented by the Experiment class in the program and to store the
experiment status is the task of this class; so we would like to implement in this class the
storeObject() method to store objects passed as arguments. It follows that all the parameters - all the
objects stored - should be of the same type.

The solution of this dilemma - the method requires objects of the same type as parameters, but we have
objects of at least two distinct types belonging to different class hierarchies - is to use a suitable interface
that contains the store() and restore() methods. We will use the Storable identifier for this
interface. The Source, Generator and Particle classes should be modified as follows:

// Interface simulation in C++


class Storable
{
public:
virtual void store(ostream&) = 0;
virtual void restore(istream&) = 0;
};

class Generator: public Storable


// Interface implementation
{
public:
virtual void store(ostream& out)
{/* Store the generator */}
virtual void restore(istream& in)
{/* Read the generator and reconstruct it */}
// ... Other methods and attributes as before
};
class Source: public Storable
// Interface implementation
{
public:
virtual void store(ostream& out)
{/* Store the source */}
virtual void restore(istream& in)

© Aptech Ltd. Version 1.0 Page 158 of 166


Object-Oriented Programming Concepts and C++ References

{/* Read the source from the file


and reconstruct it*/}
// ... Other methods and attributes as before
};

class Particle: public Storable


// Interface implementation
{
public:
virtual void store(ostream& out)
{/* Store the particle */}
virtual void restore(istream& in)
{/* Read the particle from the file
and reconstruct it */}
// ... Other methods and attributes as before
};
(ostream and istream are base classes for output and input data streams in the standard
C++ library). Figure 13.5 shows the revised UML class diagram of these classes.

Note that the Particle class is abstract, so it need not override the methods of the Storable interface.
The classes representing the concrete particle types, Electron etc., inherit the implementation of the
Storable interface; thus it is not necessary to declare this fact. Of course, if a derived class is not
abstract, it must override the methods of this interface.

Implementation of the Storable interface allows us to define the method


Experiment::storeObject() as follows:

void Experiment::storeObject(Storable& obj,


ostream& out) {
obj.store(out)
}
Storable interface serves as the common type of all the storable objects - particles as well
as random number generators - in the program. This gives us the possibility to treat all
these objects in our program in a uniform way.

Figure 7.3: The classes implementing the Storable interface

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 159 of 166


Object-Oriented Programming Concepts and C++ References

Session 8: Data Structures Using C++ and Exception


Handling
Try and Catch

Source http://www.dev-hq.net/c++/22--try-and-catch
Date of 14/05/2015
Retrieval

When programs become more complex, it is often the case that different errors and things that would
create problems should be handled (for example runtime errors). The subject of error handling, or
exception handling, is very large and complicated, and often solutions can be accomplished in a number
of ways. Some people swear by simply having if-statements that stop execution in cases that could be
problematic, and some people like having a custom function that can deal with errors by being passed
some kind of number or code. C++ provides a pretty neat way to handle exceptional circumstances
natively though, and this functionality is provided through three main keywords: try, throw, and catch.

The general idea is that code which has the potential to go wrong in some way is wrapped in a try block,
using the throw keyword when it encounters an exception, and then one of the catch blocks which follows
the try block can handle the exception in some way. A nice example to demonstrate the use of this
might be a simple application which divides two numbers, like the following:

#include <iostream>

using namespace std;

int divide_numbers(int a, int b)


{
return a/b;
}

int main()
{
int a, b;
cout << "Number one: ";
cin >> a;
cout << "Number two: ";
cin >> b;

cout << divide_numbers(a, b);

return 0;
}

The above would work perfectly fine (not to say that it couldn't be improved by passing-by-reference and
various other things), however what would it do if the user entered 'b' as '0', since dividing by 0 is
"impossible"? The answer is that it would probably give some kind of runtime error or exception. In a "real
world" application, the user probably wouldn't know what this meant and it'd be awfully confusing for

© Aptech Ltd. Version 1.0 Page 160 of 166


Object-Oriented Programming Concepts and C++ References

everybody involved in the process of trying to help fix the problem. A nice way to deal with this might be
to use try, throw, and catch! We could surround the 'return' code in the function in a try block, use an
if-statement to throw an exception if 'b' is 0, and then catch the exception and cout some kind of error.
So conceptually, something like the following:

try
{
if(b==0)
//Throw an exception

return a/b;
}
//Catch the exception

The throw statement behaves much like return. You can (and usually do) pass it a value, and then this
value is passed as a parameter into the catch block. Often either int or string-esque data-types are
thrown as they can either represent an error code or text explaining the error, however it isn't uncommon
for some custom class to be thrown either. In this example, we're just going to throw an integer error code
and then output the error:

int divide_numbers(int a, int b)


{
try
{
if(b==0)
throw 1;

return a/b;
}
catch(int err_code)
{
cout << "ERROR CODE " << err_code;
}
}

We also ought to return something, as currently nothing is returned if division by 0 is attempted. Since
execution usually continues like nothing happens after "try-catch" sections, we can simply place some
kind of error return after all of this:

int divide_numbers(int a, int b)


{
try
{
if(b==0)
throw 1;
return a/b;
}
catch(int err_code)
{
cout << "ERROR CODE " << err_code;

© Aptech Ltd. Version 1.0 Page 161 of 166


Object-Oriented Programming Concepts and C++ References

}
//Continue doing whatever afterwards like normal

return -1; //Uh oh!


}

This is not, however, an ideal solution. Firstly, we're having to take up memory copying the error code as
a parameter into the catch block - we could solve this by making the block take a reference: catch(int&
err_code), and secondly we're still outputting '-1' to the user, even if we know these results are not
accurate.

To resolve the second of these issues, we can make use of the fact that throw works its way back to find
the "closest" try-catch block that it can. In this case, it would be perfectly fine (and in many ways better)
for our function to do the throwing, however to avoid putting the try-catch block in there. If we put the
function call inside a try-catch block, the throw would still trigger any matching catch blocks! Take, for
example, the following, which prevents output if an integer exception is thrown:

int divide_numbers(int a, int b)


{
if(b==0)
throw 1;
return a/b;
}

int main()
{
int a, b;

cout << "One: ";


cin >> a;
cout << "Two: ";
cin >> b;

try
{
cout << divide_numbers(a, b);
}
catch(int& code)
{
cout << "ERROR CODE: " << code;
}
//Continue doing whatever afterwards like normal

return 0;
}

In a case like the above, we may not, however, know that an exception with an integer will be thrown. If
an exception with an integer is thrown, then brilliant, output that integer as an error code, but if any other
kind of exception is thrown, we currently aren't dealing with it. A default catch can be made by giving an
ellipsis as a parameter - this should be at the bottom of the chain if there are multiple catch statements as
it will handle any and all exceptions. An example implementation is as follows:

© Aptech Ltd. Version 1.0 Page 162 of 166


Object-Oriented Programming Concepts and C++ References

int divide_numbers(int a, int b)


{
if(b==0)
throw 1;
return a/b;
}

int main()
{
int a, b;

cout << "One: ";


cin >> a;
cout << "Two: ";
cin >> b;

try
{
cout << divide_numbers(a, b);
}
catch(int& code)
{
cout << "ERROR CODE: " << code;
}
catch(...)
{
cout << "An unknown error has occurred.";
}
//Continue doing whatever afterwards like normal

return 0;
}
There are some cases in which it's especially good practice to use a try-catch block. Dynamically
allocating memory is a prime example of this -- if we allocate memory using the new keyword and not
enough memory is available, an exception of type "bad_alloc" will be thrown. This inherits from the base
"exception" class which can be found in <exception>, which is a standard class for exceptions. Provoking
the what member function on an "exception" object should tell us what its problem was, and this can be
seen by trying to allocate a large amount of data - 100000000000000 was enough for my machine:
int main()
{
try
{
int* myarray = new int[100000000000000];
delete [] myarray;
}
catch(exception& e) //Takes a reference to an 'exception' object
{
cout << "Error allocating memory: " << e.what() << endl;
}
}

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 163 of 166


Object-Oriented Programming Concepts and C++ References

Error and Exception Handling

Source http://www.boost.org/community/error_handling.html
Date of 14/05/2015
Retrieval

Guidelines
When should I use exceptions?

The simple answer is: ``whenever the semantic and performance characteristics of exceptions are
appropriate.''

An oft-cited guideline is to ask yourself the question ``is this an exceptional (or unexpected) situation?''
This guideline has an attractive ring to it, but is usually a mistake. The problem is that one person's
``exceptional'' is another's ``expected'': when you really look at the terms carefully, the distinction
evaporates and you're left with no guideline. After all, if you check for an error condition, then in some
sense you expect it to happen, or the check is wasted code.

A more appropriate question to ask is: ``do we want stack unwinding here?'' Because actually handling an
exception is likely to be significantly slower than executing mainline code, you should also ask: ``Can I
afford stack unwinding here?'' For example, a desktop application performing a long computation might
periodically check to see whether the user had pressed a cancel button. Throwing an exception could
allow the operation to be cancelled gracefully. On the other hand, it would probably be inappropriate to
throw and handle exceptions in the inner loop of this computation because that could have a significant
performance impact. The guideline mentioned above has a grain of truth in it: in time critical code,
throwing an exception should be the exception, not the rule.

How should I design my exception classes?

1. Derive your exception class from std::exception. Except in *very* rare circumstances
where you can't afford the cost of a virtual table, std::exception makes a reasonable exception
base class, and when used universally, allows programmers to catch "everything" without
resorting to catch(...). For more about catch(...), see below.
2. Use virtual inheritance. This insight is due to Andrew Koenig. Using virtual inheritance from your
exception's base class(es) prevents ambiguity problems at the catch-site in case someone throws
an exception derived from multiple bases which have a base class in common:

#include <iostream>
struct my_exc1 : std::exception { char const* what() const throw(); };
struct my_exc2 : std::exception { char const* what() const throw(); };
struct your_exc3 : my_exc1, my_exc2 {};

int main()
{
try { throw your_exc3(); }
catch(std::exception const& e) {}
catch(...) { std::cout << "whoops!" << std::endl; }
}

The program above prints "whoops" because the C++ runtime can't resolve which exception
instance to match in the first catch clause.

© Aptech Ltd. Version 1.0 Page 164 of 166


Object-Oriented Programming Concepts and C++ References

3. Don't embed a std::string object or any other data member or base class whose copy
constructor could throw an exception. That could lead directly to std::terminate() at the throw
point. Similarly, it's a bad idea to use a base or member whose ordinary constructor(s) might
throw, because, though not necessarily fatal to your program, you may report a different
exception than intended from a throw-expression that includes construction such as:

throw some_exception();

There are various ways to avoid copying string objects when exceptions are copied, including
embedding a fixed-length buffer in the exception object, or managing strings via reference-
counting. However, consider the next point before pursuing either of these approaches.

4. Format the what() message on demand, if you feel you really must format the message.
Formatting an exception error message is typically a memory-intensive operation that could
potentially throw an exception. This is an operation best delayed until after stack unwinding has
occurred, and presumably, released some resources. It's a good idea in this case to protect your
what() function with a catch(...) block so that you have a fallback in case the formatting
code throws
5. Don't worry too much about the what() message. It's nice to have a message that a
programmer stands a chance of figuring out, but you're very unlikely to be able to compose a
relevant and user-comprehensible error message at the point an exception is thrown. Certainly,
internationalization is beyond the scope of the exception class author. Peter Dimov makes an
excellent argument that the proper use of a what() string is to serve as a key into a table of error
message formatters. Now if only we could get standardized what() strings for exceptions thrown
by the standard library.
6. Expose relevant information about the cause of the error in your exception class' public
interface. A fixation on the what() message is likely to mean that you neglect to expose
information someone might need in order to make a coherent message for users. For example, if
your exception reports a numeric range error, it's important to have the actual numbers involved
available as numbers in the exception class' public interface where error reporting code can do
something intelligent with them. If you only expose a textual representation of those numbers in
the what() string, you will make life very difficult for programmers who need to do something
more (e.g. subtraction) with them than dumb output.
7. Make your exception class immune to double-destruction if possible. Unfortunately, several
popular compilers occasionally cause exception objects to be destroyed twice. If you can arrange
for that to be harmless (e.g. by zeroing deleted pointers) your code will be more robust.

What About Programmer Errors?

As a developer, if I have violated a precondition of a library I'm using, I don't want stack unwinding. What I
want is a core dump or the equivalent - a way to inspect the state of the program at the exact point where
the problem was detected. That usually means assert() or something like it.

Sometimes it is necessary to have resilient APIs which can stand up to nearly any kind of client abuse,
but there is usually a significant cost to this approach. For example, it usually requires that each object
used by a client be tracked so that it can be checked for validity. If you need that sort of protection, it can
usually be provided as a layer on top of a simpler API. Beware half-measures, though. An API which
promises resilience against some, but not all abuse is an invitation to disaster. Clients will begin to rely on
the protection and their expectations will grow to cover unprotected parts of the interface.

Note for Windows developers: unfortunately, the native exception-handling used by most Windows
compilers actually throws an exception when you use assert(). Actually, this is true of other
programmer errors such as segmentation faults and divide-by-zero errors. One problem with this is that if
you use JIT (Just In Time) debugging, there will be collateral exception-unwinding before the debugger

© Aptech Ltd. Version 1.0 Page 165 of 166


Object-Oriented Programming Concepts and C++ References

comes up because catch(...) will catch these not-really-C++ exceptions. Fortunately, there is a simple
but little-known workaround, which is to use the following incantation:

extern "C" void straight_to_debugger(unsigned int, EXCEPTION_POINTERS*)


{
throw;
}
extern "C" void (*old_translator)(unsigned, EXCEPTION_POINTERS*)
= _set_se_translator(straight_to_debugger);

This technique doesn't work if the SEH is raised from within a catch block (or a function called from within
a catch block), but it still eliminates the vast majority of JIT-masking problems.

How should I handle exceptions?

Often the best way to deal with exceptions is to not handle them at all. If you can let them pass through
your code and allow destructors to handle cleanup, your code will be cleaner.

Avoid catch(...) when possible


Unfortunately, operating systems other than Windows also wind non-C++ "exceptions" (such as thread
cancellation) into the C++ EH machinery, and there is sometimes no workaround corresponding to the
_set_se_translator hack described above. The result is that catch(...) can have the effect of
making some unexpected system notification at a point where recovery is impossible look just like a C++
exception thrown from a reasonable place, invalidating the usual safe assumptions that destructors and
catch blocks have taken valid steps to ensure program invariants during unwinding.

I reluctantly concede this point to Hillel Y. Sims, after many long debates in the newsgroups: until all
OSes are "fixed", if every exception were derived from std::exception and everyone substituted
catch(std::exception&) for catch(...), the world would be a better place.

Sometimes, catch(...), is still the most appropriate pattern, in spite of bad interactions with
OS/platform design choices. If you have no idea what kind of exception might be thrown and you really
must stop unwinding it's probably still your best bet. One obvious place where this occurs is at language
boundaries.

~~~ End of Article ~~~

© Aptech Ltd. Version 1.0 Page 166 of 166

You might also like