Assignment operator:
The assignment operator is used
to copy the values from one object to another already existing object.
Copy constructor:
A copy constructor is
a special constructor that initializes a new object from an existing
object.
#include <iostream>
output:
#include <iostream>
using namespace std;
class Base{
public:
Base(){}
Base(const
Base &t){
cout << "Copy
constructor" << endl;
}
Base& operator = (const Base &t)
{
cout << "Assignment
operator " << endl;
return *this;
}
};
int main(void){
Base objA, objB;
objA = objB; /* Assignment
operator is called */
Base objC = objA; /* Copy
constructor is called */
system("pause");
return 0;
}
- When instantiating one object and initializing it with values from another object (as in the example above).
- When passing an object by value.
- When an object is returned from a function by value.
Case 1: It is already shown in the previous example.
case 2: Passing an object by value.
#include <iostream>
#include <iostream>
using namespace std;
class Base{
public:
Base(){}
Base(const
Base &t){
cout << "Copy
constructor is called" << endl;
}
};
void
callByValue(Base obj){
/* It will result
in creating a temporary object and assigning of the obj to temp obj */
/* Hence calls
copy constructor */
}
int main(void){
Base objA;
/* Passing an
object (objA) by value in function callByValue */
callByValue(objA);
return 0;
}
output:
Case 3: Returning object by Value.
#include <iostream>
using namespace std;
class Base{
public:
Base(){}
Base(const
Base &t){
cout << "Copy
constructor is called" << endl;
}
};
Base returnByValue(){
Base objTemp;
/* Passing by
value results calling of copy constructor */
return
objTemp;
}
int main(void){
Base objA;
objA = returnByValue();
return 0;
}
output:

In all the above mentioned cases a new variable needs to be created which results in the use of copy constructor.
Why copy constructor or overloaded assignment operator ?
Compiler
normally provide a default copy constructor and default assignment operator and
it uses a method known as Shallow copy (also known as member wise copy).
Shallow
copy
Each member of the class individually using the
assignment operator. The standard
pointer assignment operator just copies the address of the pointer — it does
not allocate any memory or copy the contents being pointed to!
Both
the objects in this case points to the same memory location and hence any
modification or deletion of the memory by one object may lead to lots of
trouble. When classes are simple (e.g. do not contain any dynamically allocated
memory), shallow copy works very well.
Lets see example what we discussed above. Consider the program below.
#include <iostream>
using namespace std;
class Base{
public:
int *p;
public:
Base(){
p = new
int;
cout << "Base
constructor allocating p" << endl;
}
~Base(){
delete
p;
cout << "Base
destructor deleting p" << endl;
}
};
int main(void){
Base objA;
/* Default copy
constructor provided by compiler will copy objA.p to objB.p */
/* Both will be
pointing the same location */
Base objB = objA;
/* Both points to
the same location */
cout << "objA.p:
0x" << objA.p << endl;
cout << "objB.p:
0x" << objB.p << endl;
return 0;
}
output:
RUN TIME ERROR
Explaination:
- Class contains the dynamic variable and its memory get allocated in constructor.
- Assigning objA to objB, results in the bitwise copy of the variable and hence objB.p gets the same location that is being assigned to objA.p( objA.p and objB.p points to same location - as shown above in output )
- Since objA and objB are local variable, hence it will be stored in stack. So when the main program is going to exit, it removes (pops) all local variables, it has stored in stack. Hence the destructor of the class is called for the objects.
- May be destructor objA is called first which deletes the memory pointed by objA.p.
- The memory pointed by objB.p is already deleted by destructor of objA, hence when objB calls its destructor during exit, it tries to delete the location which is already deleted and hence the program crashes and run time errors.
So inorder to overcome such problem Deep copying method is used. Copy constructor and assignment operator use deep copying technique.
Let write copy constructor and assignment operator to avoid this problem.
Copy constructor
Points:
- It is constructor , it has the same name as class and does not have any return type.
- Since it needs to copy an existing object, it needs to take Base class object as a parameter.
- Copy constructor is a member function of Base class and parameter is also a object of Base class, hence it can directly access the private data of the parameter.
- The parameter must be passed by reference, not by value. Passing by value again results in the creation of the temporary Base class object which will call copy constructor again. This will result in infinite recursion until stack memory runs out.
Without copy constructor.
#include <iostream>
using namespace std;
class Base{
public:
int *p;
public:
Base(){
p = new
int;
*p = 10;
cout << "Base
constructor allocating p" << endl;
}
~Base(){
delete
p;
cout << "Base
destructor deleting p" << endl;
}
};
int main(void){
Base objA;
Base objB = objA;
cout << "objA.p:
0x" << objA.p << "
*objA.p: " << *objA.p << endl;
cout << "objB.p:
0x" << objB.p << "
*objB.p: " << *objB.p << endl;
return 0;
}
output:
Note:
Both class object points to same memory location.
After printing "Base destructor deleting p", program crashes.
With copy constructor
#include <iostream>
using namespace std;
class Base{
public:
int *p;
public:
Base(){
p = new
int;
*p = 10;
cout << "Base
constructor allocating p" << endl;
}
~Base(){
delete
p;
cout << "Base
destructor deleting p" << endl;
}
/* Copy
constructure */
Base ( const
Base &obj){
p = new
int;
*p = *obj.p;
cout << "Copy
constructor called" << endl;
}
};
int main(void){
Base objA;
Base objB = objA;
cout << "objA.p:
0x" << objA.p << "
*objA.p: " << *objA.p << endl;
cout << "objB.p:
0x" << objB.p << "
*objB.p: " << *objB.p << endl;
return 0;
}
output:

Note:
Copy constructor provides a different pointer and copies the value in the new pointer.
Const is used in the copy constructor. The reason it should receive a
const parameter is that you're not changing the object you're copying from.
Overloaded Assignment Operator
First point to note that it is possible in C++ to do a self-assignment.
So it is a good idea to do a check for self-assignment at the top of an overloaded assignment operator.
It almost have identical code that is present in the copy constructor.
with overloaded assignment operator.
#include <iostream>
#include <iostream>
using namespace std;
class Base{
public:
int *p;
public:
Base(){
p = new
int;
*p = 10;
cout << "Base
constructor allocating p" << endl;
}
~Base(){
delete
p;
cout << "Base
destructor deleting p" << endl;
}
/* Copy
constructure */
Base ( const
Base &obj){
p = new
int;
*p = *obj.p;
cout << "Copy
constructor called" << endl;
}
/* Overloaded
assignment operator */
Base& operator=
(const Base &obj){
cout << "Assignment
operator constructor called" << endl;
/* Self
assignment check */
/* if both
the address is same do nothing return */
if( this == &obj)
return
*this;
/* Code same
as copy constructor */
p = new
int;
*p = *obj.p;
/* return the
existing object */
return
*this;
}
};
int main(void){
Base objA;
Base objB;
objB = objA;
cout << "objA.p:
0x" << objA.p << "
*objA.p: " << *objA.p << endl;
cout << "objB.p:
0x" << objB.p << "
*objB.p: " << *objB.p << endl;
return 0;
}
ouput:
Both the objects have pointers pointing to different location.




very good blog for programmers........... freshers..........embedded......
ReplyDeleteThanks Ram....
ReplyDelete