Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
• Lecture Notes • Lecture Notes • Lecture Notes • Lecture Notes • Lecture Notes
• Project Reports • Project Reports • Project Reports • Project Reports • Project Reports
• Solved Papers • Solved Papers • Solved Papers • Solved Papers • Solved Papers
View More » View More » View More » View More » View More »
Please note none of the content or study material in this document or content in this file is prepared or
owned by Studynama.com. This content is shared by our student partners and we do not hold any
copyright on this content.
Please let us know if the content in this file infringes any of your copyright by writing to us at:
info@studynama.com and we will take appropriate action.
1
Unit-1/Lecture-1
Object-oriented programming (OOP) [RGPV/June2014(7),June2013(8),
June2011(10), Feb2010(10),June2009 (10)]
OOPs languages are designed to overcome these problems.
The basic unit of OOP is a class, which encapsulates both the static attributes and dynamic
behaviors within a box , and specifies the public interface for using these boxes. Since the class is
well-encapsulated (compared with the function), it is easier to reuse these classes. In other words,
OOP combines the data structures and algorithms of a software entity inside the same box.
1.
OOP languages permit higher level of abstraction for solving real-life problems. The traditional
procedural language (such as C and Pascal) forces you to think in terms of the structure of the
computer (e.g. memory bits and bytes, array, decision, loop) rather than thinking in terms of the
problem you are trying to solve. The OOP languages (such as Java, C++, C#) let you think in the
problem space, and use software objects to represent and abstract entities of the problem space
to solve the problem.
m
o
.c
a
m
a
n
y
d
u
t
Benefits of OOP
S
The procedural-oriented languages focus on procedures, with function as the basic unit. You need
to first figure out all the functions and then think about how to represent data.
The object-oriented languages focus on components that the user perceives, with objects as the
basic unit. You figure out all the objects by putting all the data and operations that describe the
user’s interaction with the data.
Object-Oriented technology has many benefits:
Ease in software design as you could think in the problem space rather than the machine’s bits
and bytes. You are dealing with high-level concepts and abstractions. Ease in design leads to more
productive software development.
Ease in software maintenance: object-oriented software are easier to understand, therefore
easier to test, debug, and maintain.
Reusable software: you don’t need to keep re-inventing the wheels and re-write the same
functions for different situations. The fastest and safest way of developing a new application is to
reuse existing codes – fully tested and proven codes.
2
m
o
Encapsulation[RGPV/June2009 (2)]
Definition: the ability of an object to hide its data and methods from the rest of the world – one
.c
of the fundamental principles of OOP. Because objects encapsulate data and implementation, the
user of an object can view the object as a black box that provides services. Instance variables and
a
methods can be added, deleted, or changed, but as long as the services provided by the object
remain the same, code that uses the object can continue to use it without being rewritten.
Inheritance
m
a
Multiple classes may share some of the same characteristics, and have things in common with
one another, but also may have certain properties that make them different. Object oriented
n
programming languages allow classes to inherit commonly used state and ehavior from other
y
classes.
Classes in Java occur in inheritance hierarchies. These hierarchies consist of parent child
d
relationships among the classes. Inheritance is used to specialize a parent class, but creating a
child class (example). Inheritance also allows designers to combine features of classes in a
common parent.
u
t
Merits & demerits of OOPs
S
OOP stands for object oriented programming. It offers many benefits to both the
developers and the users. Object-orientation contributes to the solution of many
problems associated with the development and quality of software products. The new
technology promises greater programmer productivity, better quality of software and
lesser maintenance cost. The primary advantages are:
Merits:
• Through inheritance, we can eliminate redundant code and extend the use of existing
classes.
• We can build programs from the standard working modules that communicate with one
another, rather than having to start writing the code from scratch. This leads to saving of
development time and higher productivity.
• The principle of data hiding helps the programmer to build secure programs that
Studynama.com - #1 destination for free notes, eBooks, papers & projects.
Choose your course/study level below and start downloading:
Demerits: .c
· It requires more data protection. a
· Inadequate for concurrent problems
m
a
· Inability to work with existing systems.
· Compile time and run time overhead.
·
n
Unfamiliraity causes training overheads.
y
S.NO d
RGPV QUESTIONS Year Marks
Q.2
u
What are the benefits and risks of object June2010, June- 10
t
oriented development? 2009
Q.3 Write short notes on encapsulation. June-2009 2
Q.3
S Explain the feature of OOP with the help of June2013
example.
8
Unit-1/Lecture-2
Studynama.com - #1 destination for free notes, eBooks, papers & projects.
Choose your course/study level below and start downloading:
Programs are made up of modules, which are parts of a program that can be coded and tested
separately, and then assembled to form a complete program. In procedural languages (i.e. C)
these modules are procedures, where a procedure is a sequence of statements. In C for example,
procedures are a sequence of imperative statements, such as assignments, tests, loops and
invocations of sub procedures. These procedures are functions, which map arguments to return
statements.
The design method used in procedural programming is called Top Down Design. This is where
you start with a problem (procedure) and then systematically break the problem down into sub
problems (sub procedures). This is called functional decomposition, which continues until a sub
problem is straightforward enough to be solved by the corresponding sub procedure. The
difficulties with this type of programming, is that software maintenance can be difficult and time
consuming. When changes are made to the main procedure (top), those changes can cascade to
the sub procedures of main, and the sub-sub procedures and so on, where the change may impact
all procedures in the pyramid.
One alternative to procedural programming is object oriented programming. Object oriented
m
programming is meant to address the difficulties with procedural programming. In object
o
oriented programming, the main modules in a program are classes, rather than procedures. The
object-oriented approach lets you create classes and objects that model real world objects.
.c
Object Interaction: OOP: Class Hierarchy [RGPV/Feb2010(10),June2009(10)]
Object Interaction a
m
In object-oriented programming, a class is a template that defines the state and behavior common
to objects of a certain kind. A class can be defined in terms of other classes. For example, a truck
a
and a racing car are both examples of a car. Another example is a letter and a digit being both a
single character that can be drawn on the screen. In the latter example, the following terminology
is used:
n
y
The letter class is a subclass of the character class; (alternative names: child class and derived
class)
d
The character class is immediate superclass (or parent class) of the letter class;
u
The letter class extends the character class.
t
The third formulation expresses that a subclass inherits state (instance variables) and behaviour
S
(methods) from its superclass (es). Letters and digits share the state (name, font, size, position)
and behaviour (draw, resize,) defined for single characters.
The purpose of a subclass is to extend existing state and behavior: a letter has a case (upper and
lower case, say stored in the instance variable letter Case) and methods for changing the case
(toUpperCase, toLowerCase) in addition to the state that it already has as a character.
However, a digit does not have a case, so the methods toUpperCase, toLowerCase do not belong
on the common level of the Character class. There are methods that are special to the digit class.
For instance, a digit may be constructed from an integer value between 0 and 9, and conversely,
the integer value of a digit may be the result of say the intValue method.
Subclasses can also override inherited behavior: if you had a colored character as subclass of the
character class, you would override the definition of the draw method of the character class so
that color is taken into account when drawing the character on the screen. This leads to what is
called in OOP jargon polymorphism: the same message sent to different objects results in
behavior that is dependent on the nature of the object receiving the message.
In graphical terms, the above character example may look as follows:
5
m
o
.c
a
m
a
n
y
You are not limited to just one layer of inheritance: for example, the letter class can have on its
d
turn the subclasses vowel and consonant.
u
t
S
The classes form a class hierarchy, or inheritance tree, which can be as deep as needed. The
6
hierarchy of classes in Java has one root class, called Object, which is superclass of any class.
Instance variable and methods are inherited down through the levels. In general, the further
down in the hierarchy a class appears, the more specialized its behavior. When a message is sent
to an object, it is passed up the inheritance tree starting from the class of the receiving object
until a definition is found for the method. This process is called upcasting. For instance, the
method toString() is defined in the Object class. So every class automatically has this method. If
you want that your particular toString() method looks differently, you can reimplement it in your
class. In this way you can override a method in a given class by redefining it in a subclass.
In graphical terms, the inheritance tree and the message handling may look as follows:
m
o
.c
a
m
a
n
y
d
u
t
S
The picture showing the overriding of methods, may look as follows:
7
m
o
.c
a
S.NO RGPV QUESTIONS Year Marks
Q.1 Write the comparison between POP & OOPs. RGPV Feb-2010 10
m
Q.2 What is meant by hierarchy of classes? RGPV Feb-2010 10
a
n
y
d
u
t
S
Unit-1/Lecture-3
8
#include <iostream>
using namespace std;
struct X {
private:
int i;
static int si;
public:
void set_i(int arg) { i = arg; }
static void set_si(int arg) { si = arg; }
void print_i() {
cout << "Value of i = " << i << endl;
cout << "Again, value of i = " << this->i << endl;
m
o
}
static void print_si() {
.c
cout << "Value of si = " << si << endl;
// cout << "Again, value of si = " << this->si << endl;
a
}
};
m
int X::si = 77; // Initialize static data member
int main() {
a
X xobj;
xobj.set_i(11);
xobj.print_i();
n
y
// static data members and functions belong to the class and
// can be accessed without using an object of class X
d
X::print_si();
X::set_si(22);
X::print_si();
u
t
}
The following is the output of the above example:
S
Value of i = 11Again, value of i = 11Value of si = 77
Value of si = 22
The compiler does not allow the member access operation this->si in
function A::print_si() because this member function has been declared as static, and therefore
does not have a this pointer.
You can call a static member function using the this pointer of a nonstatic member function. In the
following example, the nonstatic member function printall()calls the static member
#include <iostream>
using namespace std;
class C {
static void f() {
cout << "Here is i: " << i << endl;
9
}
static int i;
int j;
public:
C(int firstj): j(firstj)
{}
void printall();
};
void C::printall() {
cout << "Here is j: " << this->j << endl;
this->f();
}
int C::i = 3;
int main() {
C obj_C(0);
}
obj_C.printall();
m
The following is the output of the above example:
o
.c
Here is j: 0
Here is i: 3
a
A static member function cannot be declared with the keywords virtual, const, volatile, or const
volatile.
m
A static member function can access only the names of static members, enumerators, and nested
a
types of the class in which it is declared. Suppose a static member function f() is a member of
class X. The static member function f() cannot access the nonstatic members X or the non static
n
members of a base class of X.
y
Passing object parameter [RGPV/June2010(10),Dec,Feb2010 (10)]
d
Procedure to Pass Object to Function
u
t
S
#include <iostream>
class Complex
private:
int real;
int imag;
public:
void Read()
{ m
o
.c
cout<<"Enter real and imaginary number respectively:"<<endl;
cin>>real>>imag;
}
a
void Add(Complex comp1,Complex comp2)
m
{
a
n
real=comp1.real+comp2.real;
y
d
/* Here, real represents the real data of object c3 because this function is called using
u
code c3.add(c1,c2); */
t
S
imag=comp1.imag+comp2.imag;
/* Here, imag represents the imag data of object c3 because this function is called using
code c3.add(c1,c2); */
void Display()
cout<<"Sum="<<real<<"+"<<imag<<"i";
};
int main()
11
Complex c1,c2,c3;
c1.Read();
c2.Read();
c3.Add(c1,c2);
c3.Display();
return 0;
Output
12
3 m
o
.c
Enter real and imaginary number respectively:
6
Sum=14+9iReturning Object from Function
a
The syntax and
m
a
Procedure to return object is similar to that of returning structure from function.
n
y
d
u
t
S
#include <iostream>
class Complex
private:
int real;
int imag;
public:
void Read()
m
o
{
.c
cout<<"Enter real and imaginary number respectively:"<<endl;
cin>>real>>imag;
a
m
}
t
/* Here, real represents the real data of object c1 because this function is called using
S
code c1.Add(c2) */
temp.imag=imag+comp2.imag;
/* Here, imag represents the imag data of object c1 because this function is called using
code c1.Add(c2) */
return temp;
void Display()
cout<<"Sum="<<real<<"+"<<imag<<"i";
13
};
int main()
Complex c1,c2,c3;
c1.Read();
c2.Read();
c3=c1.Add(c2);
c3.Display();
return 0;
m
o
}
.c
S.NO RGPV QUESTIONS Year Marks
Q.1 Explain the different methods of passing object June,Feb-2010 10
Q.2
parameters.
a
Define a class to represent distance in felt and June-2011 10
m
inch. Write a C++ program to add two distance
object taken from keyboard. Use operator
overloading.
a
n
y
d
u
t
S
14
Unit-1/Lecture 4
A friend function of a class is defined outside that class’ scope but it has the right to access all
private and protected members of the class. Even though the prototypes for friend functions
appear in the class definition, friends are not member functions.
A friend can be a function, function template, or member function, or a class or class template, in
which case the entire class and all of its members are friends.
To declare a function as a friend of a class, precede the function prototype in the class definition
with keyword friend as follows:
class Box
double width;
public: m
o
.c
double length;
a
friend void printWidth( Box box );
m
a
};
n
To declare all member functions of class ClassTwo as friends of class ClassOne, place a following
y
declaration in the definition of class ClassOne:
d
friend class ClassTwo;
u
Consider the following program:
t
#include <iostream>
S
using namespace std;
class Box
double width;
public:
width = wid;
m
o
cout << Width of box : << box.width <<endl;
.c
}
{
a
Box box;
n
y
// set box width without member function
d
u
box.setWidth(10.0);
t
// Use friend function to print the wdith.
S
printWidth( box );
return 0;}
Unit-1/Lecture 5
16
Constructors are the special type of member function that initializes the object
automatically when it is created Compiler identifies that the given member function is a
constructor by its name and return type. Constructor has same name as that of class and
it does not have any return type.
….. … …..
class temporary
{
private:
int x;
float y;
public:
temporary(): x(5), y(5.5) /* Constructor */
{
/* Body of constructor */
}
m
…. … ….
}
int main()
o
.c
{
Temporary t1;
…. … ….
}
Working of Constructor a
m
In the above pseudo code, temporary() is a constructor. When the object of
class temporary is created, constructor is called and x is initialized to 5 and y is initialized
to 5.5 automatically.
a
n
You can also initialize data member inside the constructor’s function body as below. But,
this method is not preferred.
y
Temporary(){
x=5;
y=5.5;
d
u
}
/* This method is not preferred. /*
t
S
Use of Constructor in C++
Suppose you are working on 100’s of objects and the default value of a data member is 0.
Initializing all objects manually will be very tedious. Instead, you can define a constructor
which initializes that data member to 0. Then all you have to do is define object and
constructor will initialize object automatically. These types of situation arises frequently
while handling array of objects. Also, if you want to execute some codes immediately
after object is created, you can place that code inside the body of constructor.
Constructor Example
#include <iostream>
17
class Area
private:
int length;
int breadth;
public:
void GetLength()
m
o
cout<< Enter length and breadth respectively: ;
.c
cin>>length>>breadth;
}
a
m
int AreaCalculation() { return (length*breadth); }
};
t
int main()S
{
Area A1,A2;
int temp;
A1.GetLength();
temp=A1.AreaCalculation();
A1.DisplayArea(temp);
cout<<endl<< Default Area when value is not taken from user <<endl;
Studynama’s BDS Community is one of India’s Largest Community of Dental Students. About
19,232 Indian Dental Course students are members of this community and share FREE study
material, cases, projects, exam papers etc. to enable each other to do well in their semester exams.
temp=A2.AreaCalculation();
A2.DisplayArea(temp);
return 0;
Explanation
In this program, a class of name Area is created to calculate the area of a rectangle.
There are two data members’ length and breadth. A constructor is defined which
initializes length to 5 and breadth to 2. And, we have three additional member
functions GetLength(), AreaCalculation() and DisplayArea() to get length from user,
calculate the area and display the area respectively.
When, objects A1 and A2 are created then, the length and breadth of both objects are
initialized to 5 and 2 respectively because of the constructor. Then the member
function GetLength() is invoked which takes the value of length and breadth from user
for object A1. Then, the area for the object A1 is calculated and stored in
variable temp by calling AreaCalculation() function. And finally, the area of object A1 is
m
displayed. For object A2, no data is asked from the user. So, the value of length will be 5
o
and breadth will be 2. Then, the area for A2 is calculated and displayed which is 10.
Output
.c
Enter length and breadth respectively: 6
7
a
Area: 42
Default Area when value is not taken from user
Area: 10
m
a
Constructor Overloading
Constructor can be overloaded in similar way as function overlo ading. Overloaded
n
constructors have same name(name of the class) but different number of argument
passed. Depending upon the number and type of argument passed, specific constructor is
y
called. Since, constructor are called when object is created. Argument to the constructor
d
also should be passed while creating object. Here is the modification of above program
to demonstrate the working of overloaded constructors.
u
t
/* Source Code to demonstrate the working of overloaded constructors */
S
#include <iostream>
class Area
private:
int length;
int breadth;
19
public:
void GetLength()
cin>>length>>breadth;
m
o
{
.c
cout<< Area: <<temp<<endl;
}
a
m
};
int main()
a
{
n
Area A1,A2(2,1); y
d
u
int temp;
t
cout<< Default Area when no argument is passed. <<endl;
S
temp=A1.AreaCalculation();
A1.DisplayArea(temp);
temp=A2.AreaCalculation();
A2.DisplayArea(temp);
return 0;
Advanced Java Antenna & wave Electrical Machine-1 pdf Automobile engineering lecture
Surveying 1 - eBook
Programming eBook propagation eBook download notes
Web Technology - Network analysis & Electrical machines-II Engineering materials & SOM - strength of
eBook synthesis notes eBook metallurgy lecture notes materials - eBook
For object A1, no argument is passed. Thus, the constructor with no argument is invoked
which initializeslength to 5 and breadth to 2. Hence, the area of object A1 will be 10. For
object A2, 2 and 1 is passed as argument. Thus, the constructor with two argument is
called which initializes length to l(2 in this case) and breadth to b(1 in this case.). Hence
the area of object A2 will be 2.
Output
Default Area when no argument is passed.
Area: 10
Area when (2,1) is passed as argument.
Area: 2
a
S.NO RGPV QUESTIONS Year Marks
Q.1 What is the constructor? Explain different type Feb2010, June2014 10
of constructors.
Q.2
m
Explain why do we need to use constructors? June2013 8
a
Explain a copy constructor with an example.
n
y
d
u
t
S
Unit-1/Lecture 6
Destructors are usually used to deallocate memory and do other cleanup for a class object and its
class members when the object is destroyed. A destructor is called for a class object when that
object passes out of scope or is explicitly deleted.
A destructor is a member function with the same name as its class prefixed by a ~ (tilde). For
example:
class X {
public:
// Constructor for class X
X();
// Destructor for class X
~X();
};
A destructor takes no arguments and has no return type. Its address cannot be taken. Destructors
cannot be declared const, volatile, const volatile orstatic. A destructor can be declared virtual or
pure virtual.
If no user-defined destructor exists for a class and one is needed, the compiler implicitly declares
a destructor. This implicitly declared destructor is an inline public member of its class.
The compiler will implicitly define an implicitly declared destructor when the compiler uses the
m
destructor to destroy an object of the destructor’s class type. Suppose a class A has an implicitly
o
declared destructor. The following is equivalent to the function the compiler would implicitly
define for A:
A::~A() { }
.c
a
The compiler first implicitly defines the implicitly declared destructors of the base classes and
nonstatic data members of a class A before defining the implicitly declared destructor of A
m
A destructor of a class A is trivial if all the following are true:
It is implicitly defined
a
All the direct base classes of A have trivial destructors
n
The classes of all the nonstatic data members of A have trivial destructors
y
If any of the above are false, then the destructor is nontrivial.
A union member cannot be of a class type that has a nontrivial destructor.
d
Class members that are class types can have their own destructors. Both base and derived classes
can have destructors, although destructors are not inherited. If a base class A or a member
u
of A has a destructor, and a class derived from A does not declare a destructor, a default
t
destructor is generated.
S
The default destructor calls the destructors of the base class and members of the derived class.
The destructors of base classes and members are called in the reverse order of the completion of
their constructor:
The destructor for a class object is called before destructors for members and bases are called.
Destructors for nonstatic members are called before destructors for base classes are called.
Destructors for nonvirtual base classes are called before destructors for virtual base classes are
called.
When an exception is thrown for a class object with a destructor, the destructor for the
temporary object thrown is not called until control passes out of the catch block.
Destructors are implicitly called when an automatic object (a local object that has been
declared auto or register, or not declared as static or extern) or temporary object passes out of
scope. They are implicitly called at program termination for constructed external and static
objects. Destructors are invoked when you use the delete operator for objects created with
the new operator.
Studynama’s Law Community is one of India’s Largest Community of Law Students. About
29,982 Indian Law students are members of this community and share FREE study material,
cases, projects, exam papers etc. to enable each other to do well in their semester exams.
Links to Popular Study Material for LAW (LLB & BA.LLB) students:
• Family law pdf lecture notes & eBook download for LLB students
• Jurisprudence Law lecture notes pdf & eBook download for LLB students
• Company Law lecture notes pdf & eBook download for LLB students
• Law of Evidence lecture notes pdf & eBook download for LLB students
• Contract Law lecture notes pdf & eBook download for LLB students
• Criminal law pdf lecture notes & eBook download for LLB students
• Taxation Law lecture notes pdf & eBook download for LLB students
• Law of torts pdf eBook & lecture notes for LLB students
• Constitutional law pdf lecture notes & eBook download
• Labour law lecture notes pdf & eBook download for LLB students
• Administrative law lecture notes pdf & eBook download for LLB students
• Constitutional Law - I q&a notes pdf & eBook download for LLB
And 1998 more free downloads for Law & LLB Students.
For example:
#include <string>
class Y {
private:
char * string;
int number;
public:
// Constructor
Y(const char*, int);
// Destructor
~Y() { delete[] string; }
};
a
Y yobj = Y( somestring , 10);
// …
m
a
// Destructor ~Y is called before
// control returns from main()
n
}
y
You can use a destructor explicitly to destroy objects, although this practice is not recommended.
d
However to destroy an object created with the placement newoperator, you can explicitly call the
object’s destructor. The following example demonstrates this:
u
t
#include <new>
#include <iostream>
class A {
public:
S
using namespace std;
The statement A* ap = new (p) A dynamically creates a new object of type A not in the free store
but in the memory allocated by p. The statement delete [] p will delete the storage allocated by p,
but the run time will still believe that the object pointed to by ap still exists until you explicitly call
23
m
o
.c
a
m
a
n
y
d
u
t
S
Unit-1/Lecture-7
Use the Features window to change the features of a constructor, including its arguments and
initialization code. Double-click the constructor in the IBM® Rational® Rhapsody® browser to open
its Features window.
.c
For example, to initialize a class attribute called a to 5, type the following code:
a(5)
a
• Note: In C++, this assignment is generated into the following code in the class
implementation file to initialize the data member in the constructor initializer rather than in the
m
constructor body:
//-------------------------------------------------------
a
// A.cpp
//-------------------------------------------------------
A::A() : a(5) {
n
y
//#[operation A()
//#]
d
};
S.NO
u
RGPV QUESTIONS Year Marks
t
Q.1 What are Global constructor and destructor? Dec-2010 10
Unit1/Lecture-8
MBA/PGDM first Enterprise resource Security analysis & Business environment MBA Operations
year notes planning (ERP) pdf portfolio Mgmt. Notes Notes
And 12,998 more free downloads for MBA & PGDM Students.
int i;
int main() {
int i;
i=9;
}There are two is - one inside main and one outside. Which i is set to 9? By default the "nearest"
one is, the one inside main (we'll come back to what is meant by "nearest" later in this article).
The other i isn't visible (it's covered up by main's i) but it's "in scope" so it can be accessed.
C++'s scope resolution operator (:: ) is used when specifying where to look for a variable in such
circumstances. In this case the scope to be searched is the one that encloses the current one.
Using ::i accesses the variable there.
Namespaces
m
A namespace defines a scope. It's like a context which determines the meaning of a symbol. Just
o
as the meaning of "Cambridge" will change depending on whether you're in a UK or US context, so
the variable accessed in a C++ program by the symbol "i" will depend on the context, as we've
.c
seen above.
Some simple languages only have one namespace - all function names, variable names, etc belong
a
to the same context. Some other languages have several independent namespaces (one for
variable names, one for function names, etc) making it possible to have both a variable and
m
function with the same name, but the number and role of these namespaces are fixed.
C++ has some fixed namespaces, but it also has named namespaces and lets users create new
a
namespaces. It also offers control over which of these named namespaces will be used when the
meaning of a symbol is required.
n
In ANSI C++ the standard library facilities (like cout, string, etc) are kept inside the namespace
y
called std, which by default isn't consulted. Namespaces are created and entities put into them by
using namespace. E.g.
namespace test { d
u
t
int i;
S
};creates a namespace called test (if one hasn't already been created) and puts i into it.
Then test::i (the same notation that you'd use were test an object) will access the i variable. The
command using namespace test will make available all the things inside test so that test:: isn't
necessary. Let's see this in action
namespace test {
int i;
};
int i;
int main() {
i=9;
26
}In this program main can only see one i, the other is hidden inside the test namespace. The latter
is in scope and can be accessed using test::i. What about the following though?
namespace test {
int i;
};
int i;
int main() {
i=9;
}Here both is are visible from main. In fact they clash so this program won't compile. My compiler
says The declarations "int i" and "int test::i" are both visible and neither is preferred under the
name lookup rules.
m
Classes o
.c
Functions can be in a class or free standing. Whenever a function call is processed there may be
several available functions in scope with the same name. C++ performs a look-up using a well-
a
defined strategy in order to decide which function to call. Sometimes it can't decide which
function is best to call, in which case the compiler complains about an "ambiguous call". Usually
m
there are no problems - the programmer and compiler agree on the best option. In the following
for example, there's a free-standing fun(float f) as well as one in the class. The fun(f) call
a
in main calls the free-standing one. The call from inside the class calls the "nearer" one inside the
class.
t
void fun(float f){};
};
S
void fun2(float f){fun(f);};
int main() {
float f;
fun(f);
classy c;
c.fun2(f);
}
Functions add a complication because it's possible to have many functions with the same name all
visible without clashing as long as they take different arguments. In the following
example fun is overloaded - which isn't a problem!
int main () {
fun(3);
fun(5,7);
int main () {
int i=3;
m
fun(i);
o
}
.c
a
There's no function called fun that takes an integer so fun(float f) is called without complaint. In
the next example fun(int) is supplied, so this will be the prefered candidate.
S
None of that should be too disturbing, but what about the following? Which f function is called?
The first might look like the closest match, but it's the second that's called, because the char* to
bool conversion is built into C/C++, and matches using standard conversions take precedence over
user-defined ones.
#include <iostream>
#include <string>
};
};
int main()
f("one", "two");
Inheritance
Often you'll need to add extra functionality to an existing class. C++ provides a mechanism to build
new classes from old ones
class Base {
public:
int value1;
m
};
o
.c
class More : public Base {
a
public:
int value2;
m
a
};
n
int main() {
y
Base b;
d
b.value1=7;
u
More m;
t
m.value1=7;
}
S
m.value2=9;
Here More inherits the members of Base so m has 2 members - value1 and value2. Members can
be functions or variables. The following, which uses functions where the previous example used
variables, works ok.
class Base {
public:
void fun1(){};
};
public:
void fun2(){};
};
int main() {
Base b;
b.fun1();
More m;
m.fun1();
m.fun2();
Now we come to our first "interesting program". Suppose we give both functions the same name
but different arguments. What happens?
m
class Base {
o
.c
public:
a
void fun1(){};
};
m
a
class More : public Base {
n
public:
y
void fun1(int i){};
d
};
u
int main() {
Base b;
t
S
b.fun1();
More m;
m.fun1();
m.fun1(5);
b.fun1() poses no problem. One might expect m.fun1() to call the Base's function and m.fun1(5) to
callMore's function (i.e. expect fun1 to be overloaded). In fact the code doesn't compile - void
fun1() is masked by void fun1(int). With an extra line it will compile
class Base {
public:
30
void fun1(){};
};
public:
};
int main() {
Base b;
b.fun1();
More m;
m.fun1(); m
o
.c
m.fun1(5);
}Function Lookup
And here's another surprising situation. The following compiles, but why?
namespace test { a
class T {}; m
a
n
void f(T){};
};
y
test::T parm;
d
u
t
int main() {
S
f(parm); // OK: calls test::f
}Here we have a namespace called test inside which there's a class T and a function that takes
one argument of type T. Outside the namespace a variable called parm is created. Note that
the test:: is needed to get hold of the T within this namespace. In main a function f is called. Even
though there's no test::before the function name, and no previous using namespace test line, the
program compiles.
This is a situation where Koenig lookup (also called Argument-Dependent name Lookup - ADL) is
used. If you supply a function argument that isn't a built-in type (here parm, of type test::T), then
to find the function name the compiler is required to look in the namespace (in this case test) that
contains the argument's type as well as in the usual places.
Ordinary name look-up searches for qualified names in the nearest enclosing scope where the
name is used, and if not found, the look-up proceeds in successively enclosing scope until the
name is found. Even if the name is not appropriate for the given use, the look-up search proceeds
no further through the hierarchies. At this point ADL finishes the job.
This explains why the example in the previous section failed whereas the one in this section
31
succeeded, but the look-up mechanism seems to be defeating one of the purposes of namespaces
- the ability to hide entities. However, there's a case for saying that once T is brought out into the
open, then associated routines should become visible too. There are also pragmatic and safety
reasons why ADL is used.
Here's a simple program
#include <iostream>
#include <string>
int main() {
}
This is analogous to the previous program: std::string is like the test::T of the earlier
example.operator<< is a free function that the compiler can only find using ADL (operator<< can't
m
be a member function because it requires a stream as the left-hand argument). Without ADL the
o
final line would be awkward to express.
Here's another simple fragment
char x;
.c
void f() { a
int x;
m
x = 'a'; a
n
y
}C/C++ has always set the function's x in this situation although the other x is a closer match type-
wise. ADL conforms with this traditional behaviour.
d
Here's a situation involving classes. In this fragment, the g function calls the class's f routine.
class X {
u
t
S
int f(int);
}But suppose that during program development a global function f(char) were added -
what f function should g call then? It would be an unpleasant shock if the global function were
called - you don't want the internals of classes to be quite so vulnerable to external changes.
A final note from Victor Bazarov on comp.lang.c++ - ADL applies only to function names, not
variables. The only other thing that has arguments in C++ is templates. But ADL doesn't apply to
them. In this example
namespace test {
enum foo { f };
int main() {
bar<test::f> barf;
}main's bar isn't going to be looked up in test even though its argument is fully qualified and
found in the test namespace.
m
o
.c
a
m
a
n
y
d
u
t
S
Unit-1/Lecture-9
The mechanism that allows us to extend the definition of a class without making any physical
changes to the existing class is inheritance.
Inheritance lets you create new classes from existing class. Any new class that you create from an
existing class is called derived class; existing class is called base class.
The inheritance relationship enables a derived class to inherit features from its base class.
Furthermore, the derived class can add new features of its own. Therefore, rather than create
completely new classes from scratch, you can take advantage of inheritance and reduce software
complexity.
Forms of Inheritance
Single Inheritance: It is the inheritance hierarchy wherein one derived class inherits from one
base class.
Multiple Inheritance: It is the inheritance hierarchy wherein one derived class inherits from
multiple base class(es).
Hierarchical Inheritance: It is the inheritance hierarchy wherein multiple subclasses inherit from
one base class.
m
Multilevel Inheritance: It is the inheritance hierarchy wherein subclass acts as a base class for
other classes.
o
.c
Hybrid Inheritance: The inheritance hierarchy that reflects any legal combination of other four
a
types of inheritance.
In order to derive a class from another, we use a colon (:) in the declaration of the derived class
using the following format :
m
class derived_class: memberAccessSpecifier base_class
a
{
...
n
};
Where derived_class is the name of the derived class and base_class is the name of the class on
y
which it is based. The member Access Specifier may be public, protected or private. This access
d
specifier describes the access level for the members that are inherited from the base class.
Member
u How Members of the Base Class Appear in the Derived
t
Access Class
Specifier
In principle, a derived class inherits every member of a base class except constructor and
destructor. It means private members are also become members of derived class. But
they are inaccessible by the members of derived class.
Following example further explains concept of inheritance :
class Shape
{
protected:
float width, height;
public:
void set_data (float a, float b)
{
width = a;
height = b;
m
}
};
o
.c
class Rectangle: public Shape
{
a
public:
float area ()
{
return (width * height);
m
};
}
a
n
class Triangle: public Shape
{ y
public:
d
u
float area ()
t
{
return (width * height / 2);
}; S }
int main ()
{
Rectangle rect;
Triangle tri;
rect.set_data (5,3);
tri.set_data (2,5);
cout << rect.area() << endl;
cout << tri.area() << endl;
return 0;
}
output :
35
15
5
The object of the class Rectangle contains :
width, height inherited from Shape becomes the protected member of Rectangle.
set_data() inherited from Shape becomes the public member of Rectangle
area is Rectangle’s own public member.
Polymorphism[RGPV/June2009 (10)]
The word polymorphism means having many forms. Typically, polymorphism occurs when
there is a hierarchy of classes and they are related by inheritance.
C++ polymorphism means that a call to a member function will cause a different function
m
to be executed depending on the type of object that invokes the function.
Consider the following example where a base class has been derived by other two classes:
#include <iostream> o
.c
using namespace std;
class Shape {
protected: a
int width, height;
public: m
Shape( int a=0, int b=0)
a
{
width = a; n
height = b;
y
}
int area() d
{
u
t
cout << "Parent class area :" <<endl;
S
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0):Shape(a, b) { }
36
int area ()
{
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// Main function for the program
int main( )
{
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
.c
shape->area();
}
return 0;
a
m
When the above code is compiled and executed, it produces the following result:
a
Parent class area
Parent class area
n
The reason for the incorrect output is that the call of the function area() is being set once
y
by the compiler as the version defined in the base class. This is called static resolution of
the function call, or static linkage - the function call is fixed before the program is
d
executed. This is also sometimes called early binding because the area() function is set
u
during the compilation of the program.
But now, let's make a slight modification in our program and precede the declaration of
t
area() in the Shape class with the keyword virtual so that it looks like this:class Shape {
S
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
virtual int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};
After this slight modification, when the previous example code is compiled and executed,
37
.c
meaningful definition you could give for the function in the base class.
We can change the virtual function area() in the base class to the following:
class Shape {
protected: a
int width, height;
public: m
Shape( int a=0, int b=0)
a
{
width = a; n
height = b;
y
}
d
// pure virtual function
u
virtual int area() = 0;
};
t
S
The = 0 tells the compiler that the function has no body and above virtual function will be
called pure virtual function.
m
o
.c
a
m
a
n
y
d
u
t
S
1
Unit-2/ Lecture-1
Note: The following class diagrams were modelled using Enterprise Architect. Many other
modelling tools exist. Use the one that is best suited for your purpose and project.
m
Classes
Object-oriented classes support the object-oriented principles of abstraction,
o
encapsulation, polymorphism and reusability. They do so by providing a template, or
.c
blueprint, that defines the variables and the methods common to all objects that are
based on it. Classes specify knowledge (attributes) - they know things - and behaviour
a
(methods) - they do things.
m
Classes are specifications for objects.
Derived from the Use Cases, classes provide an abstraction of the requirements and
a
provide the internal view of the application.
Attributes:-
n
y
Attributes define the characteristics of the class that, collectively, capture all the
d
information about the class. Attributes should be protected by their enclosing class.
Unless changed by the class’ behavior, attributes maintain their values.
u
The type of data that an attribute can contain is determined by its data type. There are
t
two basic data types: Primitive and Derived.
Primitive data types are fundamental types. Examples are integer, string, float.
S
Derived data types are defined in terms of the Primitive data types, that is, they form
new data types by extending the primitive data types. A Student class, for example, is a
derived data type formed by a collection of primitive data types.
When defined in the context of a problem domain, derived data types are called Domain
Specific Data types. These are the types that define and constrain attributes to be
consistent with the semantics of the data. For example, Address student
Address versus string student Address.
Object composition
programming.
When, in a language, objects are typed, types can often be divided into composite and
non composite types, and composition can be regarded as a relationship between types:
an object of a composite type (e.g. car) "has an" object of a simpler type (e.g. wheel).
Composition must be distinguished from sub typing, which is the process of adding detail
to a general data type to create a more specific data type. For instance, cars may be a
specific type of vehicle: car is a vehicle. Sub typing doesn't describe a relationship
between different objects, but instead, says that objects of a type are simultaneously
objects of another type.
m
be known as fields, members, properties or attributes, and the resulting composition as
a structure, storage record, tuple, user-defined type (UDT), or composite type. Fields are
o
given a unique name so that each one can be distinguished from the others. However,
.c
having such references doesn't necessarily mean that an object is a composite. It is only
called composite if the objects it refers to are really its parts, i.e. have no independent
existence.
m
Q.1 Compare the class diagram & object diagram. Feb-2010 5
a
Q.2 Compare the class attributes & method. Feb-2010 5
n
y
d
u
t
S
3
m
o
.c
a
m
a
n
y
d
u
t
S
4
Unit-2/Lecture-3
The whole point of OOP is that your code replicates real world objects, thus making your
code readable and maintainable. When we say real world, the real world has
relationships. Let’s consider the simple requirement listed below:
1. Manager is an employee of XYZ limited corporation.
2. Manager uses a swipe card to enter XYZ premises.
3. Manager has workers who work under him.
4. Manager has the responsibility of ensuring that the project is successful.
5. Manager's salary will be judged based on project success.
If you flesh out the above five point requirement, we can easily visualize four
relationships:-
Inheritance
m
o
Aggregation
Association
.c
Composition
Let’s understand them one by one.
n
class Employee, and a child class Manager which will inherit from the Employee class.
Note: The scope of this article is only limited to aggregation, association, and
y
composition. We will not discuss inheritance in this article as it is pretty straightforward
d
and I am sure you can get 1000s of articles on the net which will help you in
understanding it.
u
t
Requirement 2: The Using relationship: Association
S
Requirement 2 is an interesting requirement (Manager uses a swipe card to enter XYZ
premises). In this requirement, the manager object and the swipe card object use each
other but they have their own object life time. In other words, they can exist without
each other. The most important point in this relationship is that there is no single owner.
The above diagram shows how the SwipeCard class uses the Manager class and the
Manager class uses the SwipeCard class. You can also see how we can create objects of
the Manager class and SwipeCard class independently and they can have their own
object life time.
This relationship is called the Association relationship.
m
the project object, it needs the manager object.
This relationship is termed as the composition relationship. In this relationship, both
o
objects are heavily dependent on each other. In other words, if one goes for garbage
.c
collection the other also has to be garbage collected, or putting from a different
perspective, the lifetime of the objects are the same. That’s why I have put in the
a
heading Death relationship.
m
Putting things together
Below is a visual representation of how the relationships have emerged from the
requirements.
Summarizing a
n
To avoid confusion henceforth for these three terms, I have put forward a table below
y
which will help us compare them from three angles: owner, lifetime, and child object.
d
Association Aggregation Composition
Owner No owner Single owner Single owner
u
Life time Have their own lifetime Have their own lifetime Owner's life time
Child
t
Child objects all are Child objects belong to a Child objects belong to a
S
object independent single parent single parent
The first expression is used to allocate memory to contain one single element of
type type. The second one is used to allocate a block (an array) of elements of type type,
where number_of_elements is an integer value representing the amount of these. For
example:
1 int * foo;
2 foo = new int [5];
In this case, the system dynamically allocates space for five elements of type int and
returns a pointer to the first element of the sequence, which is assigned to foo (a
pointer). Therefore, foo now points to a valid block of memory with space for five
elements of type int.
m
o
.c
a
Here, foo is a pointer, and thus, the first element pointed to by foo can be accessed
either with the expressionfoo[0] or the expression *foo (both are equivalent). The second
m
element can be accessed either with foo[1] or *(foo+1), and so on...
a
There is a substantial difference between declaring a normal array and allocating
n
dynamic memory for a block of memory using new. The most important difference is that
the size of a regular array needs to be a constant expression, and thus its size has to be
y
determined at the moment of designing the program, before it is run, whereas the
d
dynamic memory allocation performed by new allows to assign memory during runtime
using any variable value as size.
u
t
The dynamic memory requested by our program is allocated by the system from the
S
memory heap. However, computer memory is a limited resource, and it can be
exhausted. Therefore, there are no guarantees that all requests to allocate memory using
operator new are going to be granted by the system.
C++ provides two standard mechanisms to check if the allocation was successful:
This exception method is the method used by default by new, and is the one used in a
declaration like:
foo = new int [5]; // if allocation fails, an exception is thrown
7
The other method is known as nothrow, and what happens when it is used is that when a
memory allocation fails, instead of throwing a bad_alloc exception or terminating the
program, the pointer returned by new is a null pointer, and the program continues its
execution normally.
This method can be specified by using a special object called nothrow, declared in
header <new>, as argument fornew:
foo = new (nothrow) int [5];
In this case, if the allocation of this block of memory fails, the failure can be detected by
checking if foo is a null pointer:
int * foo;
foo = new (nothrow) int [5];
if (foo == nullptr) {
// error assigning memory. Take measures.
}
m
This no throw method is likely to produce less efficient code than exceptions, since it
o
implies explicitly checking the pointer value returned after each and every allocation.
Therefore, the exception mechanism is generally preferred, at least for critical
.c
allocations. Still, most of the coming examples will use the no throw mechanism due to
its simplicity.
a
m
a
S.NO RGPV QUESTIONS Year Marks
Q.1 Compare association, aggregation & composition. RGPV June 10
n 2010
y
d
Q.2 How objects are assigned memory dynamically in RGPV June 10
C++? Explain by giving proper examples. 2010
u
t
S
8
Unit-2/Lecture-4
.c
The second use of the operator is used to access the members declared in class scope.
Whenever a scope resolution operator is used the name of the member that follows the
a
operator is looked up in the scope of the class with the name that appears before the
operator.
m
The scope resolution operator (::) in C++ is used to define the already declared member
a
functions (in the header file with the .hpp or the .h extension) of a particular class. In the
n
.cpp file one can define the usual global functions or the member functions of the class.
To differentiate between the normal functions and the member functions of the class,
y
one needs to use the scope resolution operator (::) in between the class name and the
d
member function name i.e. ship::foo() where ship is a class and foo() is a member
function of the class ship. The other uses of the resolution operator is to resolve the
u
scope of a variable when the same identifier is used to represent a global variable, a local
t
variable, and members of one or more class(es). If the resolution operator is placed
S
between the class name and the data member belonging to the class then the data name
belonging to the particular class is referenced. If the resolution operator is placed in front
of the variable name then the global variable is referenced. When no resolution operator
is placed then the local variable is referenced.
#include <iostream>
using namespace std;
int n = 12; // A global variable
int main() {
int n = 13; // A local variable
cout << ::n << endl; // Print the global variable: 12
cout << n << endl; // Print the local variable: 13
}
9
Here, the value of a is promoted from short to int without the need of any explicit
operator. This is known as a standard conversion. Standard conversions affect
fundamental data types, and allow the conversions between numerical types (short to
int, int to float, double to int...), to or from bool, and some pointer conversions.
Converting to int from some smaller integer type, or to double from float is known as
promotion, and is guaranteed to produce the exact same value in the destination type.
Other conversions between arithmetic types may not always be able to represent the
same value exactly:
m
o
If a negative integer value is converted to an unsigned type, the resulting value
corresponds to its 2's complement bitwise representation (i.e., -1 becomes the largest
.c
value representable by the type, -2 the second largest, ...).
a
The conversions from/to bool consider false equivalent to zero (for numeric types) and to
null pointer (for pointer types); true is equivalent to all other values and is converted to
the equivalent of 1.
m
a
If the conversion is from a floating-point type to an integer type, the value is truncated
n
(the decimal part is removed). If the result lies outside the range of representable values
by the type, the conversion causes undefined behavior.
y
Otherwise, if the conversion is between numeric types of the same kind (integer-to-
d
integer or floating-to-floating), the conversion is valid, but the value is implementation-
specific (and may not be portable).
u
t
Some of these conversions may imply a loss of precision, which the compiler can signal
S
with a warning. This warning can be avoided with an explicit conversion.
For non-fundamental types, arrays and functions implicitly convert to pointers, and
pointers in general allow the following conversions:
Null pointers can be converted to pointers of any type
Pointers to any type can be converted to void pointers.
Pointer upcast: pointers to a derived class can be converted to a pointer of an accessible
and unambiguous base class, without modifying its const or volatile qualification.
assignments.
Type-cast operator: allow implicit conversion to a particular type.
For example:
// implicit conversion of classes:
#include <iostream>
using namespace std;
class A {};
class B {
public:
// conversion from A (constructor):
B (const A& x) {}
// conversion from A (assignment):
B& operator= (const A& x) {return *this;}
// conversion to A (type-cast operator)
m
operator A() {return A();}
};
o
.c
int main ()
{
a
A foo;
B bar = foo; // calls constructor
m
bar = foo; // calls assignment
foo = bar; // calls type-cast operator
return 0;
a
n
}
The type-cast operator uses a particular syntax: it uses the operator keyword followed by
y
the destination type and an empty set of parentheses. Notice that the return type is the
d
destination type and thus is not specified before the operator keyword.
Keyword explicit
u
t
On a function call, C++ allows one implicit conversion to happen for each argument. This
S
may be somewhat problematic for classes, because it is not always what is intended. For
example, if we add the following function to the last example:
void fn (B arg) {}
This function takes an argument of type B, but it could as well be called with an object of
type A as argument:
fn (foo);
This may or may not be what was intended. But, in any case, it can be prevented by
marking the affected constructor with the explicit keyword:
// explicit:
#include <iostream>
using namespace std;
class A {};
class B {
public:
11
m
o
Additionally, constructors marked with explicit cannot be called with the assignment-like
.c
syntax; In the above example, bar could not have been constructed with:
B bar = foo;
a
m
Type-cast member functions (those described in the previous section) can also be
a
specified as explicit. This prevents implicit conversions in the same way as explicit-
specified constructors do for the destination type.
n
y
Type casting [RGPV/June2011(10)]
C++ is a strong-typed language. Many conversions, specially those that imply a different
d
interpretation of the value, require an explicit conversion, known in C++ as type-casting.
u
There exist two main syntaxes for generic type-casting: functional and c-like:
t
double x = 10.3;
int y;
S
y = int (x); // functional notation
y = (int) x; // c-like cast notation
The functionality of these generic forms of type-casting is enough for most needs with
fundamental data types. However, these operators can be applied indiscriminately on
classes and pointers to classes, which can lead to code that -while being syntactically
correct- can cause runtime errors. For example, the following code compiles without
errors:
// class type-casting
#include <iostream>
using namespace std;
class Dummy {
double i,j;
};
12
class Addition {
int x,y;
public:
Addition (int a, int b) { x=a; y=b; }
int result() { return x+y;}
};
int main () {
Dummy d;
Addition * padd;
padd = (Addition*) &d;
cout << padd->result();
return 0;
}
.c
type, independently of the types they point to. The subsequent call to member result will
produce either a run-time error or some other unexpected results.
a
In order to control these types of conversions between classes, we have four specific
m
casting operators: dynamic_cast, reinterpret_cast, static_cast and const_cast. Their
a
format is to follow the new type enclosed between angle-brackets (<>) and immediately
after, the expression to be converted between parentheses.
n
y
dynamic_cast <new_type> (expression)
reinterpret_cast <new_type> (expression)
d
static_cast <new_type> (expression)
u
const_cast <new_type> (expression)
t
The traditional type-casting equivalents to these expressions would be:
S
(new_type) expression
new_type (expression)
dynamic_cast
dynamic_cast can only be used with pointers and references to classes (or with void*). Its
purpose is to ensure that the result of the type conversion points to a valid complete
object of the destination pointer type.
polymorphic classes (those with virtual members) if -and only if- the pointed object is a
valid complete object of the target type. For example:
// dynamic_cast
#include <iostream>
#include <exception>
using namespace std;
int main () {
try {
Base * pba = new Derived;
Base * pbb = new Base;
Null pointer on second type-
Derived * pd;
cast.
pd = dynamic_cast<Derived*>(pba);
m
if (pd==0) cout << "Null pointer on first type-cast.\n";
pd = dynamic_cast<Derived*>(pbb);
o
.c
if (pd==0) cout << "Null pointer on second type-
cast.\n";
d
which is disabled by default. This needs to be enabled for runtime type checking using
dynamic_cast to work properly with these types.
u
t
The code above tries to perform two dynamic casts from pointer objects of type Base*
S
(pba and pbb) to a pointer object of type Derived*, but only the first one is successful.
Notice their respective initializations:
Base * pba = new Derived;
Base * pbb = new Base;
Even though both are pointers of type Base*, pba actually points to an object of type
Derived, while pbb points to an object of type Base. Therefore, when their respective
type-casts are performed using dynamic_cast, pba is pointing to a full object of class
Derived, whereas pbb is pointing to an object of class Base, which is an incomplete object
of class Derived.
When dynamic_cast cannot cast a pointer because it is not a complete object of the
required class -as in the second conversion in the previous example- it returns a null
pointer to indicate the failure. If dynamic_cast is used to convert to a reference type and
the conversion is not possible, an exception of type bad_cast is thrown instead.
dynamic_cast can also perform the other implicit casts allowed on pointers: casting null
14
pointers between pointers types (even between unrelated classes), and casting any
pointer of any type to a void* pointer.
static_cast
static_cast can perform conversions between pointers to related classes, not only upcasts
(from pointer-to-derived to pointer-to-base), but also downcasts (from pointer-to-base to
pointer-to-derived). No checks are performed during runtime to guarantee that the
object being converted is in fact a full object of the destination type. Therefore, it is up to
the programmer to ensure that the conversion is safe. On the other side, it does not incur
the overhead of the type-safety checks of dynamic_cast.
class Base {};
class Derived: public Base {};
Base * a = new Base;
Derived * b = static_cast<Derived*>(a);
This would be valid code, although b would point to an incomplete object of the class and
could lead to runtime errors if dereferenced.
m
Therefore, static_cast is able to perform with pointers to classes not only the conversions
allowed implicitly, but also their opposite conversions.
o
.c
static_cast is also able to perform all conversions allowed implicitly (not only those with
pointers to classes), and is also able to perform the opposite of these. It can:
a
Convert from void* to any pointer type. In this case, it guarantees that if the void*
value was obtained by converting from that same pointer type, the resulting pointer
m
value is the same.
Convert integers, floating-point values and enum types to enum types.
a
n
Additionally, static_cast can also perform the following:
Explicitly call a single-argument constructor or a conversion operator.
y
Convert to rvalue references.
d
Convert enum class values into integers or floating-point values.
Convert any type to void, evaluating and discarding the value.
u
t
reinterpret_cast
S
reinterpret_cast converts any pointer type to any other pointer type, even of unrelated
classes. The operation result is a simple binary copy of the value from one pointer to the
other. All pointer conversions are allowed: neither the content pointed nor the pointer
type itself is checked.
It can also cast pointers to or from integer types. The format in which this integer value
represents a pointer is platform-specific. The only guarantee is that a pointer cast to an
integer type large enough to fully contain it (such as intptr_t), is guaranteed to be able to
be cast back to a valid pointer.
The conversions that can be performed by reinterpret_cast but not by static_cast are low-
level operations based on reinterpreting the binary representations of the types, which
on most cases results in code which is system-specific, and thus non-portable. For
example:
class A { /* ... */ };
15
class B { /* ... */ };
A * a = new A;
B * b = reinterpret_cast<B*>(a);
This code compiles, although it does not make much sense, since now b points to an
object of a totally unrelated and likely incompatible class. Dereferencing b is unsafe.
const_cast
This type of casting manipulates the constness of the object pointed by a pointer, either
to be set or to be removed. For example, in order to pass a const pointer to a function
that expects a non-const argument:
// const_cast
#include <iostream>
using namespace std;
.c
int main () {
const char * c = "sample text";
print ( const_cast<char *> (c) );
return 0; a
}
m
a
The example above is guaranteed to work because function print does not write to the
pointed object. Note though, that removing the constness of a pointed object to actually
n
write to it causes undefined behavior.
typeid
y
d
typeid allows to check the type of an expression:
u
typeid (expression)
This operator returns a reference to a constant object of type type_info that is defined in
t
the standard header <typeinfo>. A value returned by typeid can be compared with
S
another value returned by typeid using operators == and != or can serve to obtain a null-
terminated character sequence representing the data type or class name by using its
name() member.
// typeid
#include <iostream>
#include <typeinfo>
using namespace std;
a and b are of different types:
int main () {
a is: int *
int * a,b;
b is: int
a=0; b=0;
if (typeid(a) != typeid(b))
{
cout << "a and b are of different types:\n";
cout << "a is: " << typeid(a).name() << '\n';
16
o
Base* a = new Base; *b is: class Derived
Base* b = new Derived;
.c
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
cout << "*a is: " << typeid(*a).name() << '\n';
cout << "*b is: " << typeid(*b).name() << '\n';a
m
} catch (exception& e) { cout << "Exception: " << e.what() << '\n'; }
return 0;
}
a
n
Note: The string returned by member name of type_info depends on the specific
y
implementation of your compiler and library. It is not necessarily a simple string with its
typical type name, like in the compiler used to produce this output.
d
u
Notice how the type that typeid considers for pointers is the pointer type itself (both a
and b are of type class Base *). However, when typeid is applied to objects (like *a and
t
*b) typeid yields their dynamic type (i.e. the type of their most derived complete object).
S
If the type typeid evaluates is a pointer preceded by the dereference operator (*), and
this pointer has a null value, typeid throws a bad_typeid exception.
Unit-2/Lecture-5
The prevalence of programming languages such as Java, C++, Object Pascal, C#, and
Visual Basic make it incredibly clear that object-oriented technology has become the
approach of choice for new development projects. Although procedural languages such
as COBOL and PL/1 will likely be with us for decades it is clear that most organizations
now consider these environments as legacy technologies that must be maintained and
ideally retired at some point. Progress marches on.
My experience is that agile software developers, be they application developers or Agile
DBAs, must minimally have an understanding of object orientation if they are to be
effective. This includes understanding basic concepts such as inheritance,
polymorphism, and object persistence. Furthermore, all developers should have a basic
understanding of the industry-standard Unified Modeling Language (UML). A good
starting point is to understand what I consider to be the core UML diagrams – use case
m
diagrams, sequence diagrams, and class diagrams – although as I argued in An
o
Introduction to Agile Modeling and Agile Documentation you must be willing to learn
more models over time. One of the advantages of working closely with other IT
.c
professionals is that you learn new skills from them, and the most effective object
developers will learn and adapt fundamental concepts from other disciplines. An
a
example is class normalization, the object-oriented version of data normalization, a
collection of simple rules for reducing coupling and increasing cohesion within your
object designs.
m
a
This article overviews the fundamental concepts and techniques that application
n
developers use on a daily basis when working with object technology. This article is
y
aimed at Agile DBAs that want to gain a basic understanding of the object paradigm,
allowing them to understand where application developers are coming from. The
d
primary goal of this article is to provide Agile DBAs with enough of an understanding of
u
objects so that they have a basis from which to communicate with application
developers. Similarly, other articles overview fundamental data concepts, such as
t
relational database technology and data modeling that application developers need to
S
learn so that they understand where Agile DBAs are coming from.
Object-Oriented Concepts
Agile software developers, including Agile DBAs, need to be familiar with the basic
concepts of object-orientation. The object-oriented (OO) paradigm is a development
strategy based on the concept that systems should be built from a collection of reusable
components called objects. Instead of separating data and functionality as is done in the
structured paradigm, objects encompass both. While the object-oriented paradigm
sounds similar to the structured paradigm, as you will see at this site it is actually quite
different. A common mistake that many experienced developers make is to assume that
they have been doing objects all along just because they have been applying similar
software-engineering principles. To succeed you must recognize that the OO approach is
different than the structured
To understand OO you need to understand common object terminology. The critical
terms to understand are summarized in Table 1. I present a much more detailed
18
explanation of these terms in The Object Primer 3/e. Some of these concepts you will
have seen before, and some of them you haven’t. Many OO concepts, such as
encapsulation, coupling, and cohesion come from software engineering. These concepts
are important because they underpin good OO design. The main point to be made here
is that you do not want to deceive yourself – just because you have seen some of these
concepts before, it don’t mean you were doing OO, it just means you were doing good
design. While good design is a big part of object-orientation, there is still a lot more to it
than that.
m
A set of classes that are related through aggregation
hierarchy
o
Association Objects are related (associated) to other objects
Attribute Something that a class knows (data/information)
.c
A software abstraction of similar objects, a template from which objects
Class
are created
Cohesion
component or a class)
a
The degree of relatedness of an encapsulated unit (such as a
m
Collaboration Classes work together (collaborate) to fulfill their responsibilities
a
A strong form of aggregation in which the whole is completely
n
Composition responsible for its parts and each part object is only associated to the
one whole object
y
Concrete class A class that has objects instantiated from it
d
Coupling The degree of dependence between two items
The grouping of related concepts into one item, such as a class or
u
Encapsulation
component
Information
t The restriction of external access to attributes
S
hiding
Represents is a , is like , and is kind of relationships. When class B
Inheritance inherits from class A it automatically has all of the attributes and
operations that A implements (or inherits from other classes)
Inheritance
A set of classes that are related through inheritance
hierarchy
Instance An object is an instance of a class
Instantiate We instantiate (create) objects from classes
The definition of a collection of one or more operation signatures that
Interface
defines a cohesive set of behaviors
A message is either a request for information or a request to perform an
Message
action
Messaging In order to collaborate, classes send messages to each other
Multiple When a class directly inherits from more than one class
19
inheritance
A UML concept combining the data modeling concepts of cardinality
Multiplicity
(how many) and optionality.
Object A person, place, thing, event, concept, screen, or report
Main memory + all available storage space on the network, including
Object space
persistent storage such as a relational database
Something a class does (similar to a function in structured
Operation
programming)
Sometimes you need to override (redefine) attributes and/or methods
Override
in subclasses
A reusable solution to a common problem taking relevant forces into
Pattern
account
Persistence The issue of how objects are permanently stored
Persistent
An object that is saved to permanent storage
object
Different objects can respond to the same message in different ways,
m
Polymorphism enable objects to interact with one another without knowing their exact
type
Single
o
When a class directly inherits from only one class
.c
inheritance
Stereotype Denotes a common usage of a modeling element
a
Subclass If class B inherits from class A, we say that B is a subclass of A
Superclass If class B inherits from class A, we say that A is a superclass of B
m
Transient object An object that is not saved to permanent storage
a
It is important for Agile DBAs to understand the terms presented above because the
n
application developers that you work with will use these terms, and many others, on a
y
regular basis. To communicate effectively with application developers you must
understand their vocabulary, and they must understand yours. Another important
d
aspect of learning the basics of object orientation is to understand each of the diagrams
of the Unified Modeling Language (UML) – you don’t need to become a UML expert, but
u
you do need to learn the basics.
t
S
2. An Overview of the Unified Modeling Language
The goal of this section is to provide you with a basic overview of the UML, it is not to
teach you the details of each individual technique. Much of the descriptiv material in
this section is modified from The Elements of UML Style, a pocket-sized book that
describes proven guidelines for developing high-quality and readable UML diagrams, and
the examples from The Object Primer 3/e. A good starting point for learning the UML is
UML Distilled as it is well written and concise. If you want a more thorough look at the
UML, as well as other important models that the UML does not include, then you’ll find
The Object Primer 3/e to be a better option.
It is also important to understand that you don’t need to learn all of the UML notation
available to you, and believe me there’s a lot, but only the notation that you’ll use in
practice. The examples presented in this section, there is one for each UML diagram, use
the core UML. As you learn each diagram focus on learning the core notation first, you
can learn the rest of the notation over time as you need to.
20
m
Communicate the scope of a development project
Model the analysis of your usage requirements in the form of a system use case
model (Cockburn 2001a)
o
.c
Figure 1 depicts a simple use case diagram. This diagram depicts several use cases,
actors, their associations, and optional system boundary boxes. A use case describes a
a
sequence of actions that provide a measurable value to an actor and is drawn as a
horizontal ellipse. An actor is a person, organization, or external system that plays a role
m
in one or more interactions with your system. Actors are drawn as stick
figures. Associations between actors and classes are indicated in use-case diagrams, a
a
relationship exists whenever an actor is involved with an interaction described by a use
case. Associations between actors and use cases are modeled as lines connecting them
to one another, with
n
y
an optional arrowhead on one end of the line indicating the direction of the initial
d
invocation of the relationship.
u
t
S.NO RGPV QUESTIONS Year Marks
Q.1 SExplain Rambaugh’s OMT in terms of OO modelling. Dec2010,
June 2009
10,12
UNIT- 2/LECTURE- 6
21
m
If you are not in need of dynamically allocated memory anymore, you can
use delete operator, which de-allocates memory previously allocated by new operator.
The new and delete operators:
o
.c
There is following generic syntax to use new operator to allocate memory dynamically for
any data-type.
a
New data-type;
Here, data-type could be any built-in data type including an array or any user defined
data types include class or structure. Let us start with built-in data types. For example we
m
can define a pointer to type double and then request that the memory be allocated at
a
execution time. We can do this using the newoperator with the following statements:
double* pvalue = NULL; // Pointer initialized with null
n
pvalue = new double; // Request memory for the variable
y
The memory may not have been allocated successfully, if the free store had been used
up. So it is good practice to check if new operator is returning NULL pointer and take
d
appropriate action as below:
u
double* pvalue = NULL;
t
if( !(pvalue = new double ))
{
S
cout << Error: out of memory. <<endl;
exit(1);
}The malloc() function from C, still exists in C++, but it is recommended to avoid using
malloc() function. The main advantage of new over malloc() is that new doesn’t just
allocate memory, it constructs objects which is prime purpose of C++.
At any point, when you feel a variable that has been dynamically allocated is not anymore
required, you can free up the memory that it occupies in the free store with the delete
operator as follows:
delete pvalue; // Release memory pointed to by pvalueLet us put above concepts and
form the following example to show how new and delete work:
#include <iostream>
using namespace std;
22
int main ()
{
double* pvalue = NULL; // Pointer initialized with null
pvalue = new double; // Request memory for the variable
Return 0;
}
If we compile and run above code, this would produce the following result:
Value of pvalue : 29495
Dynamic Memory Allocation for Arrays:
Consider you want to allocate memory for an array of characters, i.e., string of 20
characters. Using the same syntax what we have used above we can allocate memory
dynamically as shown below.
m
o
Char* pvalue = NULL; // Pointer initialized with null
pvalue = new char[20]; // Request memory for the variable
.c
To remove the array that we have just created the statement would look like this:
delete [] pvalue; // Delete array pointed to by pvalue
a
Following the similar generic syntax of new operator, you can llocate for a multi-
dimensional array as follows:
m
double** pvalue = NULL; // Pointer initialized with null
pvalue = new double [3][4]; // Allocate memory for a 3x4 array
a
However, the syntax to release the memory for multi-dimensional array will still remain
n
same as above:
delete [] pvalue; // Delete array pointed to by pvalue
y
Dynamic Memory Allocation for Objects:
d
Objects are no different from simple data types. For example, consider the following code
where we are going to use an array of objects to clarify the concept:
u
#include <iostream>
t
using namespace std;
S
class Box
{
public:
Box() {
cout << Constructor called! <<endl;
}
~Box() {
cout << Destructor called! <<endl;
}
};
int main( )
{
Box* myBoxArray = new Box[4];
23
return 0;
}
If you were to allocate an array of four Box objects, the Simple constructor would be
called four times and similarly while deleting these objects, destructor will also be called
same number of times.
If we compile and run above code, this would produce the following result:
Constructor called!
Constructor called!
Constructor called!
Constructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!
.c
in C++.
Q.2 Describe memory allocation in C++ June2013 12
a
with the help of code
m
a
n
y
d
u
t
S
24
UNIT- 2/LECTURE- 7
Template classes[RGPV/Dec,June2010(10)]
In the previous two lessons, you learn how function templates and function template
instances could be used to generalize functions to work with many different data types.
While this is a great start down the road to generalized programming, it doesn’t solve
all of our problems. Let’s take a look at an example of one such problem, and see what
templates can do for us further.
In the lesson on container classes, you learned how to use composition to implement
classes that contained multiple instances of other classes. As one example of such a
container, we took a look at the IntArray class. Here is a simplified example of that class:
#ifndef INTARRAY_H m
#define INTARRAY_H
o
#include <assert.h> // for assert()
.c
class IntArray a
m
{
private:
int m_nLength;
a
n
int *m_pnData;
public:
y
d
IntArray()
{
u
m_nLength = 0;
t
m_pnData = 0;
}
S
IntArray(int nLength)
{
m_pnData = new int[nLength];
m_nLength = nLength;
}
~IntArray()
{
delete[] m_pnData;
}
void Erase()
{
25
#endif
m
While this class provides an easy way to create arrays of integers, what if we want to
create an array of doubles? Using traditional programming methods, we’d have to
o
create an entirely new class! Here’s an example of DoubleArray, an array class used to
.c
hold doubles.
a
#ifndef DOUBLEARRAY_H
#define DOUBLEARRAY_H
u
t
public:
DoubleArray()
{
S
m_nLength = 0;
m_pdData= 0;
}
DoubleArray(int nLength)
{
m_pdData= new double[nLength];
m_nLength = nLength;
}
~DoubleArray()
{
delete[] m_pdData;
26
void Erase()
{
delete[] m_pdData;
// We need to make sure we set m_pnData to 0 here, otherwise it will
// be left pointing at deallocated memory!
m_pdData= 0;
m_nLength = 0;
}
m
// It does not depend on the data type of the array
int GetLength() { return m_nLength; }
};
o
#endif
.c
a
Although the code listings are lengthy, you’ll note the two classes are almost identical!
m
In fact, the only substantive difference is the contained data type. As you likely have
guessed, this is another area where templates can be put to good use to free us from
a
having to create classes that are bound to one specific data type.
n
Creating template classes is works pretty much identically to creating template functions,
y
so we’ll proceed by example. Here’s the IntArray classes, templatated version:
#ifndef ARRAY_H
d
#define ARRAY_H
u
t
#include <assert.h> // for assert()
S
template <typename T>
class Array
{
private:
int m_nLength;
T *m_ptData;
public:
Array()
{
m_nLength = 0;
m_ptData = 0;
}
27
Array(int nLength)
{
m_ptData= new T[nLength];
m_nLength = nLength;
}
~Array()
{
delete[] m_ptData;
}
void Erase()
{
delete[] m_ptData;
// We need to make sure we set m_pnData to 0 here, otherwise it will
// be left pointing at deallocated memory!
m_ptData= 0;
m
m_nLength = 0;
}
o
.c
T& operator[](int nIndex)
{
a
assert(nIndex >= 0 && nIndex < m_nLength);
return m_ptData[nIndex];
m
}
a
// The length of the array is always an integer
// It does not depend on the data type of the array
n
int GetLength(); // templated GetLength() function defined below
};
y
d
template <typename T>
u
int Array<T>::GetLength() { return m_nLength; }
#endif t
S
As you can see, this version is almost identical to the IntArray version, except we’ve
added the template declaration, and changed the contained data type from int to T.
Note that we’ve also defined the GetLength() function outside of the class declaration.
This isn’t necessary, but new programmers typically stumble when trying to do this for
the first time due to the syntax, so an example is instructive. Each templated member
function declared outside the class declaration needs its own template declaration. Also,
note that the name of the templated array class is Array<T>, not Array — Array would
refer to a non-templated version of a class named Array.
int main()
28
{
Array<int> anArray(12);
Array<double> adArray(12);
return 0;
}
11 11.5 m
10 10.5
o
.c
9 9.5
8 8.5
a
7 7.5
6 6.5
m
5 5.5
4 4.5
3
2
3.5
2.5 a
1 1.5
n
0 0.5
y
d
Templated classes are instanced in the same way templated functions are — the compile
u
stencils a copy upon demand with the template parameter replaced by the actual data
t
type the user needs and then compiles the copy. If you don’t ever use a template class,
the compile won’t even compile it.
S
Template classes are ideal for implementing container classes, because it is highly
desirable to have containers work across a wide variety of data types, and templates
allow you to do so without duplicating code. Although the syntax is ugly, and the error
messages can be cryptic, template classes are truly one of C++’s best and most useful
features.
Some older compilers (eg. Visual Studio 6) have a bug where the definition of template
class functions must be put in the same file as the template class is defined in. Thus, if
the template class were defined in X.h, the function definitions would have to also go in
X.h (not X.cpp). This issue should be fixed in most/all modern compilers.
29
m
o
.c
a
m
a
n
y
d
u
t
S
UNIT -2/LECTURE -8
C++ Tutorials
In object-oriented programming languages like C++, the data and functions (procedures
to manipulate the data) are bundled together as a self-contained unit called an object. A
class is an extended concept similar to that of structure in C programming language; this
class describes the data properties alone. In C++ programming language, class describes
both the properties (data) and behaviors (functions) of objects. Classes are not objects,
but they are used to instantiate objects.
Features of Class:
Classes contain data known as members and member functions. As a unit, the collection
of members and member functions is an object. Therefore, this unit of objects makes up
a class.
m
The starting flower brace symbol '{'is placed at the beginning of the code. Following the
flower brace symbol, the body of the class is defined with the member functions data.
o
Then the class is closed with a flower brace symbol '}' and concluded with a colon ';'.
.c
1. class exforsys
2. {
a
3. data;
4. member_functions;
m
5. & #46;..........
6. };
a
There are different access specifiers for defining the data and functions present inside a
class.
n
Access specifiers:
y
Access specifiers are used to identify access rights for the data and member functions of
d
the class. There are three main types of access specifiers in C++ programming language:
private
u
t
public
protected
S A private member within a class denotes that only members of the same class
have accessibility. The private member is inaccessible from outside the class.
Public members are accessible from outside the class.
A protected access specifier is a stage between private and public access. If
member functions defined in a class are protected, they cannot be accessed from outside
the class but can be accessed from the derived class.
When defining access specifiers, the programmer must use the keywords: private, public
or protected when needed, followed by a semicolon and then define the data and
member functions under it.
1. class exforsys
2. {
3. private:
4. int x,y;
5. public:
6. void sum()
31
7. {
8. & #46;...
9. & #46;...
10. }
11. };
In the code above, the member x and y are defined as private access. The member
function sum is defined as a public access.
m
8. data_member;
9. member_functions;
10. };
o
.c
Generally, in class, all members (data) would be declared as private and the member
functions would be declared as public. Private is the default access level. If no access
a
specifiers are identified for members of a class, the members are defaulted to private
access.
m
1. class exforsys
2. {
3.
4.
int x,y;
public: a
5. void sum()
n
6.
7.
{
y
& #46;...
8.
d
& #46;...
9. }
u
t
10. };
In this example, for members x and y of the class exforsys there are no access specifiers
S
identified. exforsys would have the default access specifier as private.
Creation of Objects:
Once the class is created, one or more objects can be created from the class as objects
are instance of the class.
Just as we declare a variable of data type int as:
int x;
Objects are also declared as:
class_name followed_by object_name;
Example:
exforsys e1;
This declares e1 to be an object of class exforsys.
For example a complete class and object declaration is given below:
1. class exforsys
32
2. {
3. private:
4. int x,y;
5. public:
6. void sum()
7. {
8. & #46;...
9. & #46;...
10. }
11. };
12.
13. void main()
14. {
15. exforsys e1;
16. & #46;...
17. & #46;...
18. }
m
<="" p="">
For example:
1. class exforsys
o
.c
2. {
3. private:
a
4. int x,y;
5. public:
m
6. void sum()
7. {
8.
9.
& #46;...
& #46;... a
10. }
n
11. }e1;
y
S.NO
d
RGPV QUESTION YEAR MARKS
Q.1
u
Define object & classess in C++. RGPV Dec 2010 7
t
S
33
Unit-2/ Lecture- 9
Language Concepts
The 5 Basic Concepts of Object Oriented Design are the implementation level features that are built
the programming language. These features are often referred to by these common names:
Encapsulation-A tight coupling or association of data structures with the methods or functions that
on the data. This is called a class, or object (an object is often the implementation of a class).
m
Data Protection -The ability to protect some components of the object from external entities. This
o
realized by language keywords to enable a variable to be declared as private or protected to the ownin
class.
.c
Inheritance -The ability for a class to extend or override functionality of another class. The so called c
a
class has a whole section that is the parent class and then it has it's own set of functions and data.
m
Interface -A definition of functions or methods, and their signatures that are available for use
manipulate a given instance of an object.
a
Polymorphism -The ability to define different functions or classes as having the same name but takin
different data types.
n
Programming Concepts
y
d
There are several concepts that were derived from the new languages once they became popular.
new standards that came around pushed on three major things:
u
t
Re-usability-The ability to reuse code for multiple applications. If a programmer has already written
power function, then it should be written that any program can make a call to that function and it sho
S
work exactly the same.
Privacy -This is important for large programs and preventing loss of data.
Documentation -The commenting of a program in mark up that will not be converted to machine co
This mark up can be as long as the programmer wants, and allows for comprehensive information to
passed on to new programmers. This is important for both the re-usability and the maintainability
programs.