Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // deep copying in C++
- // 2026-04-16
- // tested on Win with g++
- #include <iostream>
- #include <sstream>
- #include <fstream>
- #include <exception>
- #include <stdexcept>
- #include <cfloat>
- #include <cassert>
- #include <cstdlib>
- #include <cstdio>
- using namespace std;
- class X {
- // the field below is the one that needs a special care
- int *data;
- int size;
- public:
- X(int size){
- data = new int[size];
- }
- // we provide the copy constructor and implement a deep copy
- X(const X& other){
- // this would be copied in the shallow copy
- // but since we provide our own copy constructor
- // default functionality becomes disabled thus we need
- // to do all the copying ourselves
- size = other.size;
- // this is the main thing - allocate the memory for the field
- // so that it lives a separate life from the original
- data = new int[size];
- // carefully transfer all the contents
- // generally if you have pointer-to-pointer-to-pointer
- // you might go deeper - hence the name "deep copy"
- // i.e. you propagate copying into deeper levels
- for(int i = 0; i < size; ++i){
- data[i] = other.data[i];
- }
- }
- // copy constructor is not enough, you also have to
- // provide assignment operator
- // Object x(copy); - this is copy constructor
- // Object x = copy; - this is also copy constructor!
- // x = copy; - this is the assignment as no new object is created
- const X& operator=(const X& other){
- // self check is an essential part, because of the delete
- // if there is self-assignment i.e. x = x, we delete x1
- // and then there is no more data to copy;
- // but for self assignment we do not need to do anything
- // because nothing changes
- if(this != &other){
- // delete is the step that is needed
- // when compared to copy constructor
- // because we have to deal with the
- // old data which becomes irrelevant
- delete [] data;
- // now the rest follows as in copy-constructor
- size = other.size;
- data = new int[size];
- for(int i = 0; i < size; ++i){
- data[i] = other.data[i];
- }
- }
- return other;
- }
- // destructor - the fact that we needed it for a class
- // to function properly, is a sign to apply the rule of three
- // thus we examine if we need deep copying because
- // shallow copying might fail us
- ~X(){
- delete [] data;
- }
- int get(int pos){
- return data[pos];
- }
- void set(int pos, int value){
- data[pos] = value;
- }
- };
- int main(){
- try {
- cout << "Hello" << endl;
- // original object
- X* x1 = new X(5);
- x1->set(0, 2);
- x1->set(1, 4);
- cout << x1->get(0) << x1->get(1) << endl;
- // another object
- X x2(6); // you can use the X x2(*x1) if you want constructor
- // assignment operation
- x2 = *x1;
- // this is disaster if shallow copy is done
- // test this by commenting out the two operations provided
- // and see what happens
- delete x1;
- x2.get(0);
- // this is just to check where the code crashes
- // i.e. if the line is reached, if your system doesn't show it
- cout << "Hello" << endl;
- } catch(...){
- cout << "Unexpected exception" << endl;
- }
- // checking also if this was reached, if not - it means
- // the program has crashed
- cout << "Hello" << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment