Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
63 views27 pages

C++ Notes

Download as pdf or txt
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 27

OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

MODULE 1

INTRODUCTION
 C++ is an object oriented programming language & is an extension of c.
 Bjarne Stroustrup at AT & Bell Lab,USA developed it.
 He called the language C with classes.
Advantages
 OOPS can be comfortably upgraded.
 Using inheritance redundant program, codes can be eliminated & use of previously defined classes
may be continued.
 OOP languages have standard class library.
Uses of OOP
 Object-Oriented DBMS
 Office automation software
 AI and expert systems
 CAD/CAM software
 Network programming
 System software
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

What Is Object-Oriented Programming?

Structured languages are characterized by their support for stand-alone subroutines, local variables, rich control
constructs, and their lack of reliance upon the GOTO.
Structured languages are a powerful tool, they reach their limit when a project becomes too large.
Object-oriented programming took the best ideas of structured programming and combined them with several
new concepts.
The result was a different way of organizing a program.
In the most general sense, a program can be organized in one of two ways: around its code (what is happening)
or around its data (who is being affected).
Using only structured programming techniques, programs are typically organized around code.
This approach can be thought of as "code acting on data."
For example, a program written in a structured language such as C is defined by its functions, any of which
may operate on any type of data used by the program.
Object-oriented programs work the other way around.
They are organized around data, with the key principle being "data controlling access to code."
In an object-oriented language, you define the data and the routines that are permitted to act on that data.
Thus, a data type defines precisely what sort of operations can be applied to that data.
To support the principles of object-oriented programming, all OOP languages have three traits in common:
encapsulation, polymorphism, and inheritance. Let's examine each.

Encapsulation
Encapsulation is the mechanism that binds together code and the data it manipulates, and keeps both safe from
outside interference and misuse.
In an object-oriented language, code and data may be combined in such a way that a self-contained "black box"
is created.
When code and data are linked together in this fashion, an object is created. In other words, an object is the
device that supports encapsulation.
Within an object, code, data, or both may be private to that object or public.
Private code or data is known to and accessible only by another part of the object.
That is, private code or data may not be accessed by a piece of the program that exists outside the object.
When code or data is public, other parts of your program may access it even though it is defined within an
object.
Typically, the public parts of an object are used to provide a controlled interface to the private elements of the
object.

Polymorphism

Object-oriented programming languages support polymorphism, which is characterized by the phrase "one
interface, multiple methods."
In simple terms, polymorphism is the attribute that allows one interface to control access to a general class of
actions.
The specific action selected is determined by the exact nature of the situation.
A real-world example of polymorphism is a thermostat.
No matter what type of furnace your house has (gas, oil, electric, etc.), the thermostat works the same way.
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

In this case, the thermostat (which is the interface) is the same no matter what type of furnace (method) you
have. For example, if you want a 70-degree temperature, you set the thermostat to 70 degrees.
It doesn't matter what type of furnace actually provides the heat.
Polymorphism helps reduce complexity by allowing the same interface to be used to access a general class of
actions.
It is the compiler's job to select the specific action (i.e., method) as it applies to each situation. The programmer,
don't need to do this selection manually.
One has to remember and utilize the general interface.
Inheritance
Inheritance is the process by which one object can acquire the properties of another object.
This is important because it supports the concept of classification.
Most knowledge is made manageable by hierarchical classifications. For example, a Red Delicious apple is part
of the classification apple, which in turn is part of the fruit class, which is under the larger class food.
Without the use of classifications, each object would have to define explicitly all of its characteristics.
However, through the use of classifications, an object need only define those qualities that make it unique within
its class.
It is the inheritance mechanism that makes it possible for one object to be a specific instance of a more general
case.

A Sample C++ Program


Let's start with the short sample C++ program shown here

#include<iostream>
using namespace std;
int main()
{
int i;
cout << "This is output.\n"; // this is a single line comment
/* you can still use C style comments */
// input a number using >>
cout << "Enter a number: ";
cin >> i;
// now, output a number using <<
cout << i << " squared is " << i*i << "\n";
return 0;
}
As one can see, this program looks much different from the C subset programs found in Part One.
A line-by-line commentary will be useful. To begin, the header is included.
This header supports C++-style I/O operations. ( is to C++ what stdio.h is to C.)
There is no .h extension to the name iostream.

using namespace std;

This tells the compiler to use the std namespace.


OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

Namespaces are a recent addition to C++.


A namespace creates a declarative region in which various program elements can be placed.
Namespaces help in the organization of large programs.
The using statement informs the compiler that one want to use the std namespace.
This is the namespace in which the entire Standard C++ library is declared.
By using the std namespace one can simplify access to the standard library.

Now examine the following line.

int main()

The parameter list in main( ) is empty.


In C++, this indicates that main( ) has no parameters.
The next line contains two C++ features

cout << "This is output.\n"; // this is a single line comment

First, the statement

cout << "This is output.\n";

This is output. to be displayed on the screen, followed by a carriage return linefeed combination. In C++, the
<< has an expanded role.

It is still the left shift operator, but when it is used as shown in this example, it is also an output operator.
The word cout is an identifier that is linked to the screen.

Use cout and the << to output any of the built-in data types, as well as strings of characters.

What follows the output expression is a C++ single-line comment.

Define a single-line comment by using //;

In general, C++ programmers use multiline comments when a longer comment is being created and use single-
line comments when only a short remark is needed.

Next, the program prompts the user for a number. The number is read from the keyboard with this statement:

cin >> i;

In C++, the >> operator still retains its right shift meaning.
However, when used as shown, it also is C++'s input operator.
This statement causes i to be given a value read from the keyboard.
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

The identifier cin refers to the standard input device, which is usually the keyboard.
In general, you can use cin >> to input a variable of any of the basic data types plus strings.
Another interesting line in the program is shown here:

cout << i << "squared is " << i*i << "\n";

Assuming that i has the value 10, this statement causes the phrase 10 squared is 100 to be displayed, followed
by a carriage return-linefeed.
As this line illustrates, one can run together several << output operations.
The program ends with this statement:
return 0;
This causes zero to be returned to the calling process (which is usually the operating system). This works the
same in C++ as it does in C.
Returning zero indicates that the program terminated normally.

INPUT & OUTPUT IN C++


Pre-defined streams
cin  Standard input, usually keyboards, corresponding to stdin in C.
 It handles input from input devices.
Cout  Standard output, usually screen, corresponding to stdout in C.
 It passes data to output devices such as monitor and printer.
clog  It control error messages that are passed from buffer to the standard error device
cerr  Standard error output, usually screen, corresponding to stderr in C.
 it controls the unbuffered output data.
 It catches the error & passes to standard error device monitor.

stream classes
Input stream
 It does read operation through keyboard.
 It uses cin as object.
 The cin statement is used to read data through the input device & uses the extraction operator “
>> “. Syntax: cin>> varname;
int a; float
b; cin>>a>>b;
Output stream
 It display contents of variables on the screen.
 It uses insertion operation “ << ” before variable
name. Syntax :
cout <<
variable; int a;
float b; cout
<<a << b;
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

Classes and Object


Classes:
Classes are created using the keyword class. A class declaration defines a new type that links code and data.
This new type is then used to declare objects of that class. Thus, a class is a logical abstraction, but an object
has physical existence. In other words, an object is an instance of a class. A class declaration is similar
syntactically to a structure. Here is the entire general form of a class declaration that does not inherit any other
class
class class-name
{
private data and functions
access-specifier:
data and functions
access-specifier:
data and functions
// ...
access-specifier:
data and functions
} object-list;

The object-list is optional. If present, it declares objects of the class. Here, access-specifier is one of these
three C++ keywords:

public
private
protected

By default, functions and data declared within a class are private to that class and may be accessed only by
other members of the class.
The public access specifier allows functions or data to be accessible to other parts of your program.
The protected access specifier is needed only when inheritance is involved.
Once an access specifier has been used, it remains in effect until either another access specifier is encountered
or the end of the class declaration is reached.

class item
{
private:
int codeno;
float price;
int qty;
public:
void value()
{
cout<<"enter codeno,price,qty";
cin>>codeno>>price>>qty;
}
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

void show()
{
cout<<codeno<<price<<qty;
}
};
int main()
{
item a;
a.value();
a.show();
return 0;
}

Objects

Public keyword – it is used to allow an object to access the member variable of a class directly
like structure.
Private keyword – it is used to prevent direct access to member variable or member function by
the object. By default the class member are private.
Protected keyword – it is same as private. It is frequently used in inheritance
Specify the object's name, the dot operator, and the variable name.

This simple program illustrates the use of a public variable:

#include<iostream>
using namespace std;
class myclass
{
public: int i, j, k; // accessible to entire program
};
int main()
{
myclass a, b; a.i = 100; // access to i, j, and k is OK
a.j = 4;
a.k = a.i * a.j;
b.k = 12; // remember, a.k and b.k are different
cout << a.k << " " << b.k;
return 0;
}

Defining member function


Program – Write a program to find simple interest using class concept & data should be declared in private
section:
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

#include<iostream>
class interest
{
private:
float p,i,r;
float s.i;
void in();
public:
void calc();
void display();
void in()
{
cout<<"enter p,i,r";
cin>>p>>i>>r;
}
void calc()
{
in();
s.i=p*i*r/100;
amt= p+s.i;
}
void display()
{
cout<<"simple interest is";
}
};
int main()
{
interest i;
i.calc();
i.display();
return 0;
}

Declaring member function outside the class using scope resolution operator

class class-name

{
access-specifier:

Member function
declaration;

};
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

return type class name:: funame()

//Function definition

Example:

#include<iostream>

class item
{
private:
int codeno;
float price;
int qty;
public:
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

void in();
void show();

};
void item::in()
{
cout<<"enter codeno,price,qty";
cin>>codeno>>price>>qty;
}

void item::show()
{
cout<<"codeno,price,qty";
cin>>codeno>>price>>qty;
}
void main()
{
item one;
one.in();
one.show();
}

Structures and Classes Are Related


Structures are part of the C subset and were inherited from the C language.
A class is syntactically similar to a struct.
But the relationship between a class and a struct is closer than you may at first think.
In C++, the role of the structure was expanded, making it an alternative way to specify a class.
In fact, the only difference between a class and a struct is that by default all members are public in a
struct and private in a class.
In all other respects, structures and classes are equivalent. That is, in C++, a structure defines a class
type.

Unions and Classes Are Related


Like a structure, a union may also be used to define a class.
In C++, unions may contain both member functions and variables.
They may also include constructors and destructors.
A union in C++ retains all of its C-like features, the most important being that all data elements share
the same location in memory.
Like the structure, union members are public by default and are fully compatible with C.

Friend Functions:
It is possible to grant a nonmember function access to the private members of a class by using a
friend. A friend function has access to all private and protected members of the class for which it is
a friend.
To declare a friend function, include its prototype within the class, preceding it with the keyword
friend. Consider this program:
#include <iostream>
using namespace std;
class myclass
{
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

int a, b;
public:
friend int sum(myclass x);
void set_ab(int i, int j);
};
void myclass::set_ab(int i, int j)
{
a = i; b = j;
} // Note: sum() is not a member function of any class.
int sum(myclass x)
{
/* Because sum() is a friend of myclass, it can directly access a and b. */
return x.a + x.b;
}
int main()
{
myclass n;
n.set_ab(3, 4);
cout << sum(n);
return 0;
}

First, friends can be useful when one is overloading certain types of operators.
Second, friend functions make the creation of some types of I/O functions easier .
The third reason that friend functions may be desirable is that in some cases, two or more classes
may contain members that are interrelated relative to other parts of your program.
Let's examine this third usage now.

Program- Write a program to addition of 3 number using friend function.


#include<iostream.h>
#include<conio.h>
class B;
class C;
class A
{
int a[5];
public:
void in();
friend C sum(A,B,C);
};
void A::in()
{
int k;
cout<<"\n enter five integer:";
for(k=0;k<5;k++)
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

cin>>a[k];
}
class B
{
int b[5];
public:
void in();
friend C sum(A,B,C);
};
void B::in()
{
int k;
cout<<"\n enter five integer:";
for(k=0;k<5;k++)
cin>>b[k];
}
class C
{
int c[5];
public:
void out();
friend C sum(A,B,C);
};
void C::out()
{
cout<<"\n
addition:"; for(int
k=0;k<5;k++)
cout<<" "<<c[k];
}
C sum(A a1,B b1,C c1)
{
for(int k=0;k<5;k++)
c1.c[k]=a1.a[k]+b1.b[k];
return c1;
}
int main()
{

A a;
B b;
C c;
a.in();
b.in();
c=sum(a,b,c);
c.out();
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

return 0;
}

 C++ allows a mechanism in which a non-member function has access permission to the private
data member of the class
 This can be done by declaring a non-member function as friend to the class whose private data is to
be accessed.

Friend Classes

It is possible for one class to be a friend of another class. When this is the case, the friend class and all of its
member functions have access to the private members defined within the other class. For example,

// Using a friend class.


#include <iostream>
using namespace std;
class TwoValues
{
int a; int b;
public:
TwoValues(int i, int j)
{
a = i; b = j;
}
friend class Min;
};
class Min
{
int min(TwoValues x);
};
int Min::min(TwoValues x)
{
return x.a < x.b ? x.a : x.b;
}
int main()
{
TwoValues ob(10, 20);
Min m;
cout << m.min(ob);
return 0;
}
In this example, class Min has access to the private variables a and b declared within the TwoValues class.
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

Inline functions

There is an important feature in C++, called an inline function, that is commonly used with classes.

In C++, you can create short functions that are not actually called; rather, their code is expanded in line at
the point of each invocation.

This process is similar to using a function-like macro.

To cause a function to be expanded in line rather than called, precede its definition with the inline
keyword.

For example, in this program, the function max( ) is expanded in line instead of called:

#include<iostream>

using namespace std;

inline int max(int a, int b)

{ return a>b ? a : b; }

int main()

cout << max(10, 20);

cout << " " << max(99, 88);

return 0;

As far as the compiler is concerned, the preceding program is equivalent to this one:

#include<iostream>

using namespace std;

int main()

cout << (10>20 ? 10 : 20);

cout << " " << (99>88 ? 99 : 88);

return 0;

}
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

Program - Write a program to find square of a


number.
#include <iostream.h>
inline float square(float j)
{ return(j*j); }
void main()
{
int p,q;
cout<<”enter a number:” ;
cin>>p;
q=square(p);
cout<<q;
}

Advantage:
As one can probably know, each time a function is called, a significant amount of overhead is generated by the
calling and return mechanism.
Typically, arguments are pushed onto the stack and various registers are saved when a function is called, and
then restored when the function returns.
The trouble is that these instructions take time.
However, when a function is expanded in line, none of those operations occur.
Although expanding function calls in line can produce faster run times, it can also result in larger code size
because of duplicated code.
For this reason, it is best to inline only very small functions.
Further, it is also a good idea to inline only those functions that will have significant impact on the performance
of the program.
Like the register specifier, inline is actually just a request, not a command, to the compiler. The compiler can
choose to ignore it.
Also, some compilers may not inline all types of functions.

Inline functions may be class member functions. For example, this is a perfectly valid C++ program:

#include<iostream>
using namespace std;
class myclass
{
int a, b;
public: void init(int i, int j);
void show();
};
// Create an inline function.
inline void myclass::init(int i, int j)
{
a = i; b = j;
} // Create another inline function.
inline void myclass::show()
{
cout << a << " " << b << "\n";
}
int main()
{
myclass x;
x.init(10, 20);
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

x.show();
return 0;
}

CONSTRUCTOR & DESTRUCTOR


1. C++ provides a pair of inbuilt special member function called constructor & destructor.
2. The constructor constructs the object allocates memory for data members & also initializes them.
3. The destructor destroys the object when it is of no use or goes out of scope & deallocates the memory.
4. The compiler automatically executes these functions.
5. When an object is created ,compiler invokes the constructor function.
6. Destructor is executed at the end of the function when objects are of no use & goes out of scope.

Example
Class num
{
Private:
int a,b,c;
public:
num();
~num();
};
num:;num()
{
a=0;b=0;c=0;
}
num::~num()
{
cout<<”destructor invoked”;
}
int main()
{
num x;
return 0;
}

Parameterized Constructors

It is possible to pass arguments to constructors.


Typically, these arguments help initialize an object when it is created.
To create a parameterized constructor, simply add parameters to it as any other function.
When you define the constructor's body, use the parameters to initialize the object.
For example, here is a simple class that includes a parameterized constructor:

#include <iostream>
using namespace std;
class myclass
{
int a, b;
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

public:
myclass(int i, int j)
{
a=i; b=j;
}
void show()
{
cout << a << " " << b;
}
};
int main()
{
myclass ob(3, 5);
ob.show();
return 0;
}

Constructors with One Parameter: A Special Case

If a constructor only has one parameter, there is a third way to pass an initial
value to that constructor.

#include <iostream>
using namespace std;
class X
{
int a; public:
X(int j)
{
a = j;
}
int geta()
{
return a;
}
};
int main()
{
X ob = 99; // passes 99 to j
cout << ob.geta(); // outputs 99
return 0;
}

Here, the constructor for X takes one parameter.


Pay special attention to how ob is declared in main( ).
In this form of initialization, 99 is automatically passed to the j parameter in the X( ) constructor.
That is, the declaration statement is handled by the compiler as if it were written like this
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

X ob = X(99);

In general, any time one can have a constructor that requires only one argument, one can use either ob(i) or
ob = i to initialize an object.

For example, consider the following short program.


#include<iostream>
class num
{
rivate:
int a,b,c;
public
: num(int m,int n,int k)
void show()
{
cout<<a<<b<<c;
}
};
num::num(int m,int j,int k)
{
a=m; b=j; c=k;
}
int main()
{
num x=num(4,5,7);
num y(1,2,8);
x.show();
y.show();
return 0;
}

Static member variable


When you precede a member variable's declaration with static, you are telling the compiler that only one copy
of that variable will exist and that all objects of the class will share that variable.
Unlike regular data members, individual copies of a static member variable are not made for each object.
No matter how many objects of a class are created, only one copy of a static data member exists.
Thus, all objects of that class use that same variable.
All static variables are initialized to zero before the first object is created
When you declare a static data member within a class, you are not defining it.
When you declare a static data member within a class, you are not defining it.
That is, you are not allocating storage for it.
Instead, you must provide a global definition for it elsewhere, outside the class. This is done by redeclaring the
static variable using the scope resolution operator to identify the class to which it belongs.
This causes storage for the variable to be allocated.

To understand the usage and effect of a static data member, consider this program:
#include <iostream>
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

using namespace std;


class shared
{
static int a; int b;
public:
void set(int i, int j)
{
a=i; b=j;
}
void show();
};
int shared::a; // define a
void shared::show()
{
cout << "This is static a: " << a;
cout << "\nThis is non-static b: " << b;
cout << "\n";
}
int main()
{
shared x, y;
x.set(1, 1); // set a to 1
x.show();
y.set(2, 2); // change a to 2
y.show();
x.show(); /* Here, a has been changed for both x and y because a is shared by both objects. */
return 0;
}
This program displays the
following output when run.

This is static a: 1
This is non-static b: 1
This is static a: 2
This is non-static b: 2
This is static a: 2
This is non-static b: 1

Another interesting use of a static member variable is to keep track of the number of objects of a particular
class type that are in existence.
For example:

#include<iostream>
using namespace std;
class Counter
{
public: static int count;
Counter()
{
count++;
}
~Counter()
{
count--;
}
};
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

int Counter::count;
void f();
int main(void)
{
Counter o1;
cout << "Objects in existence: ";
cout << Counter::count << "\n";
Counter o2;
cout << "Objects in existence: ";
cout << Counter::count << "\n";
f(); cout << "Objects in existence: ";
cout << Counter::count << "\n";
return 0;
}
void f()
{
Counter temp;
cout << "Objects in existence: ";
cout << Counter::count << "\n"; // temp is destroyed when f() returns
}

This program produces the following output.


Objects in existence: 1
Objects in existence: 2
Objects in existence: 3
Objects in existence: 2

Static Member Functions


Member functions may also be declared as static.
There are several restrictions placed on static member functions.
They may only directly refer to other static members of the class.
Of course, global functions and data may be accessed by static member functions.
A static member function does not have a this pointer.
There cannot be a static and a non-static version of the same function.
A static member function may not be virtual.
Finally, they cannot be declared as const or volatile.
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

#include<iostream>
using namespace std;
class static_type
{
static int i;
public: static void init(int x)
{
i = x;
}
void show()
{
cout << i;
}
};
int static_type::i; // define i
int main()
{ // init static data before object creation
static_type::init(100);
static_type x;
x.show(); // displays 100
return 0;
}

When Constructors and Destructors Are Executed

As a general rule, an object's constructor is called when the object comes into existence, and an object's destructor
is called when the object is destroyed.

A local object's constructor is executed when the object's declaration statement is encountered. The destructors
for local objects are executed in the reverse order of the constructor functions.

This program illustrates when constructors and destructors are executed:

#include<iostream>
using namespace std;

class myclass
{
public: i
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

nt who;
myclass(int id);
~myclass();
} glob_ob1(1), glob_ob2(2);
myclass::myclass(int id)
{
cout << "Initializing " << id << "\n";
who = id;
}
myclass::~myclass()
{
cout << "Destructing " << who << "\n";
}
int main()
{
myclass local_ob1(3);
cout << "This will not be first line displayed.\n";
myclass local_ob2(4);
return 0;
}

It displays this output:

Initializing 1
Initializing 2
Initializing 3

This will not be first line displayed.

Initializing 4
Destructing 4
Destructing 3
Destructing 2
Destructing 1

The Scope Resolution Operator

The :: operator links a class name with a member name in order to tell the compiler what class the member
belongs to. However, the scope resolution operator has another related use: it can allow access to a name in an
enclosing scope that is "hidden" by a local declaration of the same name.
For example, consider this fragment:

int i; // global i
void f()
{
int i; // local i
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

i = 10; // uses local i


...
}

As the comment suggests, the assignment i = 10 refers to the local i.


But what if function f( ) needs to access the global version of i?
It may do so by preceding the i with the :: operator, as shown here.

int i; // global i
void f() {
int i; // local i
::i = 10; // now refers to global i
...
}

Passing Objects to Functions

Objects may be passed to functions in just the same way that any other type of variable can. Objects are passed
to functions through the use of the standard call-by value mechanism.

// Passing an object to a function.


#include <iostream>
using namespace std;
class myclass
{
int i;
public:
myclass(int n);
~myclass();
void set_i(int n)
{
i=n;
}
int get_i()
{
return i;
}
};
myclass::myclass(int n)
{ i = n;
cout << "Constructing " << i << "\n";
}
myclass::~myclass()
{
cout << "Destroying " << i << "\n";
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

}
void f(myclass ob);
int main()
{
myclass o(1);
f(o);
cout << "This is i in main: ";
cout << o.get_i() << "\n";
return 0;
}
void f(myclass ob)
{
ob.set_i(2);
cout << "This is local i: " << ob.get_i();
cout << "\n";
}

This program produces this output:

Constructing 1
This is local i: 2
Destroying 2
This is i in main: 1
Destroying 1

When an object is passed to a function, a copy of that object is made.


When the function terminates, the copy of the argument is destroyed.

When a copy of an argument is made during a function call, the normal constructor is not called.
Instead, the object's copy constructor is called.

However, if a class does not explicitly define a copy constructor, as is the case here, then C++ provides one by
default.

The default copy constructor creates a bitwise (that is, identical) copy of the object.

Returning Objects

A function may return an object to the caller. For example, this is a valid C++ program:

// Returning objects from a function.


#include <iostream>
using namespace std;
class myclass
{
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

int i;
public:
void set_i(int n)
{
i=n;
}
int get_i()
{
return i;
}
};
myclass f(); // return object of type myclass
int main()
{
myclass o;
o = f();
cout << o.get_i() << "\n";
return 0;
}
myclass f()
{
myclass x;
x.set_i(1);
return x;
}

When an object is returned by a function, a temporary object is automatically created that holds the return value.
It is this object that is actually returned by the function.
After the value has been returned, this object is destroyed.
The destruction of this temporary object may cause unexpected side effects in some situations.

For example, if the object returned by the function has a destructor that frees dynamically allocated memory,
that memory will be freed even though the object that is receiving the return value is still using it.

Object Assignment

Assuming that both objects are of the same type, one can assign one object to another.
This causes the data of the object on the right side to be copied into the data of the object on the left.
For example, this program displays 99:

// Assigning objects.
#include <iostream>
using namespace std;
class myclass
{
int i;
OBJECT-ORIENTED PROGRAMMING WITH C++ BCS306B

public:
void set_i(int n)
{
i=n;
}
int get_i()
{
return i;
}
};
int main()
{
myclass ob1, ob2;
ob1.set_i(99);
ob2 = ob1; // assign data from ob1 to ob2
cout << "This is ob2's i: " << ob2.get_i();
return 0;
}
OBJECT-ORIENTED PROGRAMMING WITH C++
BCS306B

You might also like