Copy Assignment
- By default, each member of one object is copied to its counterpart in the other object
- Called when two objects have been already exist
- Object o1;
- Object o2;
- o2 = o1;
No pointer
#ifndef V_H
#define V_H
class V
{
private:
int size;
public:
V(int s):size(s){}
int getSize() const {return size;}
};
#endif
#include <iostream>
#include "V.h"
int main(int argc, char *argv[])
{
V v(10);
V v2(20);
std::cout<<"Size: "<<v.getSize()<<" "<<v2.getSize()<<std::endl;
v2 = v;
std::cout<<"Size: "<<v.getSize()<<" "<<v2.getSize()<<std::endl;
return 0;
}
Have Pointer Attributes
//V.h
#ifndef V_H
#define V_H
class V
{
private:
int size;
int *array;
public:
V(int s):size(s)
{
array = new int[size];
for(int i = 0; i < size; i++)
array[i] = 10*i;
}
int *getAddress() const {return array;}
void display() const
{
for(int i = 0; i < size; i++)
std::cout<<array[i]<<" ";
std::cout<<std::endl;
}
~V()
{
delete [] array;
array = 0;
size = 0;
}
};
#endif
#include <iostream>
#include "V.h"
int main(int argc, char *argv[])
{
V *v = new V(10);
V *v2 = new V(20);
*v2 = *v;
//both objects have same dynamic memory
std::cout<<"Address: "<<v->getAddress()<<" "<<v2->getAddress()<<std::endl;
v->display();
v2->display();
delete v;
v2->display();
return 0;
}
- Default assignmetn constructor does not work anymore, copy assignment cause two objects share the same memory
Initialize Objects
//g++ *.cpp -std=c++11
//V.h
#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)//not calll copy constructor
//const V operator=(const V &right)//calll copy constructor
{
std::cout<<"Copy Assignment ..."<<std::endl;
delete [] array;//release the current memory
array = new int[right.size];
for(int i = 0; i < right.size; i++)
array[i] = right.array[i];
size = right.size;
return *this;
}
~V()
{
std::cout<<"Destructor ..."<<std::endl;
delete [] array;
array = 0;
size = 0;
}
};
#endif
//main.cpp
#include <iostream>
#include "V.h"
int main(int argc, char *argv[])
{
V *v = new V(10);
V *v2 = new V(20);
V *v3 = new V(30);
*v3 = *v2 = *v;
v->display();
v2->display();
v3->display();
delete v;
delete v2;
delete v3;
return 0;
}
Return from Function
#include <iostream>
#include "V.h"
V getObject()
{
std::cout<<"Inside function ..."<<std::endl;
V v(10);
std::cout<<"Return from function ..."<<std::endl;
return v;
}
int main(int argc, char *argv[])
{
std::cout<<"Before calling function ..."<<std::endl;
V v(20);
v = getObject();
std::cout<<"After calling function ..."<<std::endl;
v.display();
return 0;
}
Why copy-and-swap idiom?
//g++ *.cpp -std=c++11
#ifndef V_H
#define V_H
class V
{
private:
int size;
int *array;
public:
//constructor
V(int s):size(s)
{
std::cout<<"Constructor ..."<<std::endl;
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 Copy Constructor ..."<<std::endl;
}
int *getAddress() const {return array;}
int getSize() const {return size;}
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 ..."<<size<<std::endl;
if (this != &right)//sef-assignment check
{
delete [] array;
array = nullptr;
//code duplication
size = right.size;
array = size?new int[size]:nullptr;
std::copy(right.array, right.array+size, array);
}
std::cout<<"Return from Assignment ..."<<std::endl;
return *this;
}
~V()
{
std::cout<<"Destructor ..."<<size<<std::endl;
delete [] array;
array = 0;
size = 0;
}
};
#endif
- Self-assignment check
- if new[size] fail, *this could have been modified; or copy only succesfully copied several elements and fail
- Stackoverflow
- cpluplus.com
A Successful Solution
#ifndef V_H
#define V_H
class V
{
private:
int size;
int *array;
public:
//constructor
V(int s):size(s)
{
std::cout<<"Constructor ..."<<std::endl;
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 Copy Constructor ..."<<std::endl;
}
int *getAddress() const {return array;}
int getSize() const {return size;}
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 -----------------------"<<size<<std::endl;
V temp(right);
std::swap(size, temp.size);
std::swap(array, temp.array);
std::cout<<"Ending Assignment ---------------------"<<std::endl;
return *this;
}
~V()
{
std::cout<<"Destructor ..."<<size<<std::endl;
delete [] array;
array = 0;
size = 0;
}
};
#endif
Reference
- Starting out with C++, Tony Gaddis