Deep copy constructor

it is deep copy constructor???
please explain me about deep and shallow copy constructor...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
  #include<iostream.h>

class student
{

	private:
		int num1,num2;
	public:
		student(int n1, int n2)
		{
			num1=n1;
			num2=n2;
		}
		void display()
		{
			cout<<num1<<","<<num2;
		}
		student (student &s)
		{
			num1=s.num1;
			num2=s.num2;
		}
		int getnum1()
		{
			return num1;
		}
		void setnum1(int x)
		{
			num1=num1+x;
		}
};


void main ()
{
	student obj(34,23);
	obj.display();
	student obj1=obj;
	cout<<"....object 2...."<<obj1.getnum1()<<endl;
	obj.setnum1(45);
	cout<<"object 1......"<<obj.getnum1()<<"....object 2...."<<obj1.getnum1()<<endl;
	obj1.display();
	cout<<endl;
	obj.display();

	
}
I would advice against any kind of copy constructor if the class allocates any memory! Same with assignment operators. It's dangerous! The reason is that you have no way of returning any result value from a constructor or operator that would indicate if the copying process has been successful.

I'd rather recommend something like this:

1
2
3
4
5
6
7
8
9
class student
{
    bool CopyFrom(const student& src)
    {
        // Copy all values here
        // Also copy all your allocated memory here
        // Check if new allocations were successful. If not, return false.
    }
}
Last edited on
I'd rather recommend something like this:


but can't you do this in the copy constructor? Fair enough, a compiler-generated copy ctor wont handle deep copy, but you can roll your own. You're implying you can't do a deep copy using a copy constructor?
Last edited on
You can do anything in a constructor, sure. The only thing you can't do is: Return a value that would indicate success or failure. That's why I recommend copy constructors (and overloaded assignment operators) only for classes/structs that don't allocate memory on the heap.

This might crash, if the required memory could not be allocated in obj2's copy constructor.
1
2
3
4
5
6
MyClass obj;
obj.Allocate_a_lot_of_memory();
obj.Do_something_with_that_memory();

MyClass obj2(obj);  // Use copy constructor
obj2.Do_something_with_that_memory();


This allows you to react to failure of allocation:
1
2
3
4
5
6
7
8
9
10
11
MyClass obj;
obj.Allocate_a_lot_of_memory();
obj.Do_something_with_that_memory();

MyClass obj2;  // Use copy constructor
if (!obj2.CopyFrom(obj))
{
    printf("Help, something terrible happened!");
    return;
}
obj2.Do_something_with_that_memory();
Last edited on
http://www.cplusplus.com/doc/tutorial/classes2/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// copy constructor: deep copy
#include <iostream>
#include <string>
using namespace std;

class Example5 {
    string* ptr;
  public:
    Example5 (const string& str) : ptr(new string(str)) {}
    ~Example5 () {delete ptr;}
    // copy constructor:
    Example5 (const Example5& x) : ptr(new string(x.content())) {}
    // access content:
    const string& content() const {return *ptr;}
};

int main () {
  Example5 foo ("Example");
  Example5 bar = foo;

  cout << "bar's content: " << bar.content() << '\n';
  return 0;
}
The only thing you can't do is: Return a value that would indicate success or failure.
Return error codes are frowned upon in C++. You should use exceptions for that.

That's why I recommend copy constructors (and overloaded assignment operators) only for classes/structs that don't allocate memory on the heap.
And for any class which can be a parameter for any function which takes parameters by value (which are often should be preferred in C++11).
jbottrop wrote:
I would advice against any kind of copy constructor if the class allocates any memory!
memory is such an essential resource for a program that it cannot proceed without, hence the correcte reaction is to end the program.


MiiNiPaa wrote:
Return error codes are frowned upon in C++.
What? Who said that?
coder777 wrote:
What? Who said that?

Herb Sutter and Andrei Alexandrescu in C++ Coding Standards.
Scott Meyers in one of his Effective C++ books (can't point to the actual book right now).
Bjarne Stroustrup http://www.stroustrup.com/bs_faq2.html#exceptions-why
Microsoft: http://msdn.microsoft.com/en-us/library/hh279678.aspx
Boost: http://www.boost.org/development/requirements.html#Design_and_Programming
Use exceptions to report errors where appropriate, and write code that is safe in the face of exceptions.


As with all best practices there are cases when you should ditch exceptions: in real-time systems, when writing perfomance critical code which will be compiled on compilers which dos not support zero-cost exceptions, when supporting legacy code which did was not created with exception safety in mind.
Error codes are a very C thing in my opinion. Just my opinion though.
jbottrop wrote:
I would advice against any kind of copy constructor if the class allocates any memory! Same with assignment operators. It's dangerous! The reason is that you have no way of returning any result value from a constructor or operator that would indicate if the copying process has been successful.


NO.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// deep Copy Constructor with DAM // anup 7nov2014
#include <iostream>
#include <ctime>
#include <cstdlib>

using namespace std;
bool errorDetector = false;

class T {
private:
	int *ptr; int size;
public:
	T () {ptr = NULL; size=0; } // constructor
	T ( int SIZE) // constructor
	: ptr(new  (nothrow) int[size] )
	{ 
		if(ptr==NULL)
		{
		cout <<"error\n"; 
		errorDetector = true;
		}
		else
		{
			size = SIZE;
			for (int i=0; i<size; i++)
			{
				ptr[i] = rand()%(i+1);
			}	
		}	
	} 
	

    
    T (const T &x)  // copy constructor
	: ptr(new  (nothrow) int[x.size] )
	{
		if(ptr==NULL)
		{
		cout <<"Error.\n"; 
		errorDetector = true;
		}
		else
		{
			size = x.size;
			for (int i=0; i<size; i++)
			{
				ptr[i] = x.ptr[i];
			}	
		}

	} 
    
    int content(int param)  {return ptr[param];} // access content
	~T () {delete[] ptr; cout << "ptr deleted\n";} // destructor
};

int main () {
	srand(time(NULL));
	int i=0, SIZE = 5000;
	
	T foo (SIZE);
	if(!errorDetector)
	{
		cout<< "foo created successfull, with size " << SIZE 
			<< "\nwhich foo value you want to see: ";
		cin >> i;
		cout << "foo's content: " << foo.content(i) << endl;				
	}
		
	T bar =foo; //copy constructor.
	if(!errorDetector)
		cout << "bar's content: " << bar.content(i) << endl;

return 0;
}

Last edited on
Topic archived. No new replies allowed.