Copy Constructor
- By default, C++ compiler creates a copy constructor to copy counterparts from one object to another. When class has dynamic memory allocation, define our own copy constructor
- When to call copy constructor
- When you declare a new object and initialize it with another object
- When pass an object to function by value
- When an object is constructed based on another object of the same class
- When explicity invoked in another constructor's initialization list
- When an object is a data member of another class for which the compiler has generated its own copy constructor
The Big Three
- Whenever you are writing either one of destructor, copy constructor or copy assignment operator, you probably need to write the other two
Class with Copy Constructor
#ifndef V_H
#define V_H
class V
{
private:
int size;
int *array;
public:
//constructor
V(int s):size(s)
{
array = new int[size];
for(int i = 0; i < size; i++)
array[i] = 10*i;
}
//copy constructor
V(const V &right):size(right.size), array(size?new int[size]:nullptr)
{
std::cout<<"Copy Constructor ..."<<std::endl;
std::copy(right.array, right.array+size, array);
std::cout<<"End Constructor ..."<<std::endl;
}
int *getAddress() const {return array;}
void display() const
{
for(int i = 0; i < size; i++)
std::cout<<array[i]<<" ";
std::cout<<std::endl;
}
//copy assignment
const V& operator=(const V &right)
{
std::cout<<"Copy Assignment ..."<<std::endl;
V temp(right);
std::swap(size, temp.size);
std::swap(array, temp.array);
return *this;
}
~V()
{
std::cout<<"Destructor ..."<<std::endl;
delete [] array;
array = 0;
size = 0;
}
};
#endif
When you declare a new object and initialize it with another object
#include <iostream>
#include "V.h"
int main(int argc, char *argv[])
{
V v1(10);
V v2(v1);
V v3 = v1;
v2.display();
v3.display();
return 0;
}
When pass an object to function by value
#include <iostream>
#include "V.h"
void getObject(V v)
{
v.display();
}
int main(int argc, char *argv[])
{
V v(10);
std::cout<<"Before calling function ..."<<std::endl;
getObject(v);
std::cout<<"After calling function ..."<<std::endl;
return 0;
}
When an object is constructed based on another object of the same class
#ifndef V_H
#define V_H
class V
{
private:
int size;
int *array;
public:
//constructor
V(int s):size(s)
{
array = new int[size];
for(int i = 0; i < size; i++)
array[i] = 10*i;
}
V(int s, V right):size(s), array(size?new int [size]:nullptr)
{
std::cout<<"Second Constructor ..."<<std::endl;
std::copy(right.array, right.array+size, array);
}
//copy constructor
V(const V &right):size(right.size), array(size?new int[size]:nullptr)
{
std::cout<<"Copy Constructor ..."<<std::endl;
std::copy(right.array, right.array+size, array);
std::cout<<"End Constructor ..."<<std::endl;
}
int *getAddress() const {return array;}
void display() const
{
for(int i = 0; i < size; i++)
std::cout<<array[i]<<" ";
std::cout<<std::endl;
}
//copy assignment
const V& operator=(const V &right)
{
std::cout<<"Copy Assignment ..."<<std::endl;
V temp(right);
std::swap(size, temp.size);
std::swap(array, temp.array);
return *this;
}
~V()
{
std::cout<<"Destructor ..."<<std::endl;
delete [] array;
array = 0;
size = 0;
}
};
#endif
#include <iostream>
#include "V.h"
int main(int argc, char *argv[])
{
V v(10);
V v2(20, v);
v2.display();
return 0;
}
When explicity invoked in another constructor's initialization list
- Name(string f, string l):firstName(f), lastName(l){}
When an object is a data member of another class for which the compiler has generated its own copy constructor
#ifndef V_H
#define V_H
class V
{
private:
int size;
int *array;
public:
//constructor
V()
{
std::cout<<"Default Constructor ..."<<std::endl;
size = 0;
array = 0;
}
V(int s):size(s)
{
array = new int[size];
for(int i = 0; i < size; i++)
array[i] = 10*i;
}
//copy constructor
V(const V &right):size(right.size), array(size?new int[size]:nullptr)
{
std::cout<<"Copy Constructor ..."<<std::endl;
std::copy(right.array, right.array+size, array);
std::cout<<"End Constructor ..."<<std::endl;
}
int *getAddress() const {return array;}
void display() const
{
for(int i = 0; i < size; i++)
std::cout<<array[i]<<" ";
std::cout<<std::endl;
}
//copy assignment
const V& operator=(const V &right)
{
std::cout<<"Copy Assignment ..."<<std::endl;
V temp(right);
std::swap(size, temp.size);
std::swap(array, temp.array);
return *this;
}
~V()
{
std::cout<<"Destructor ..."<<std::endl;
delete [] array;
array = 0;
size = 0;
}
};
#endif
#ifndef A_H
#define A_H
#include <iostream>
#include <string>
#include "V.h"
class A
{
private:
std::string name;
V array;
public:
A(std::string n, V v)
{
std::cout<<"--------------"<<std::endl;
name = n;
array = v;
std::cout<<"--------------"<<std::endl;
}
};
#endif
#include <iostream>
#include "A.h"
#include "V.h"
int main(int argc, char *argv[])
{
V v(10);
A a("Array", v);
return 0;
}
Reference