Copy Constructor and copy assignment operator

Hello everyone!

Can somebody explain the functionality of the Copy Constructor and copy assignment operator?

Its way too short in the Tutorial on this site :/ (here: http://www.cplusplus.com/doc/tutorial/classes/)

1
2
3
CExample::CExample (const CExample& rv) {
  a=rv.a;  b=rv.b;  c=rv.c;
  }


afaik this has something to do with the copy constructor, and it needs to be defined as const and with a reference (&).

and the next thing is where i'm really stuck right now is the topic "The keyword this"

http://www.cplusplus.com/doc/tutorial/classes2/

1
2
3
4
5
6
7
// this
#include <iostream>
using namespace std;

class CDummy {
  public:
    int isitme (CDummy& param);


ok, afaik int isitme (XXXXX) is a function, right?
CDummy& param i can only guess, but i guess its a reference to the value(s) of param. Or has it something to do with the copy constructor?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
};

int CDummy::isitme (CDummy& param)
{
  if (&param == this) return true;
  else return false;
}

int main () {
  CDummy a;
  CDummy* b = &a;
  if ( b->isitme(a) )
    cout << "yes, &a is b";
  return 0;
}


i mean i understand the code, except for the CDummy&, which confuses m :/

ah, and what does the copy assignment operator looks like? haven't found anything in the tutorial about it until now :(

any help would be appreciated.


If you don't understand me, please tell me what additional informations you need, to be able to help me :>

kind regards and thanks in advance
genbatzu~

Last edited on
The copy constructor is a constructor that makes a new object from an existing object. Because a class may contain other classes, and/or pointers, simply making a bit-wise copy is not sufficient to create a new object.

The copy assignment operator is another way of making a new object from an existing object.
It usually has the following signature:

1
2
3

CDummy & operator = ( const CDummy& C );


In the isitme() function (yes, you're right: It is a function,) the CDummy& is the address of the argument param. The "this" keyword is automatically created for your class and is a "pointer to the object for which the function was involked." (From The C++ Programming Language, Third Edition, page 231)
hello and thank you kooth! :)

let me try to understand and regive it:

 
CDummy & operator = ( const CDummy& C );


The copy assignment operator is a function of type overloaded operator "=" with a constant CDummy& parameter "C" (where CDummy& is the address of the argument "C").

This Function returns a value of Type CDummy& (where CDummy & is the address of the value returned by the function).


How does a copy constructor looks like then?
according to the tutorial here, it's the following:

1
2
3
CExample::CExample (const CExample& rv) {
  a=rv.a;  b=rv.b;  c=rv.c;
  }


so declared in class as a prototype should it be like this then?:

1
2
3
4
5
6
class CExample{
CExample& CExample (const CExample&);
.
.
.
}


So basically copy constructor and copy assignment operator do the same ? Or is there a difference?

and last but not least

Is there a difference between CDummy& C, CDummy & C and CDummy &C ?
as far as i've read, spaces are irrelevant for c++ ôo .

//edit: sry, but after loosing the text 3 times, because i got logged out while writing, i might wrote it a bit diffcult to understand :/
if something is unclear, ask me :>

anyway, thank you in advance!
kind regards
genbatzu~
I am not explain the logic here, but i think the below code block may help you somehow...

#include "iostream.h"

class Test
{
private:
int p, q;
public:
Test (int a, int b)
{
p = a;
q = b;
}
Test(Test &i)
{
p = i.p;
q = i.q;
}
void putdata1();
void putdata2();
/*void putdata1()
{
cout<<"For Constructor Test(int a, int b)"<<p<<" "<<q<<endl;
}
void putdata2()
{
cout<<"For Constructor Test(Test &i)"<<p<<" "<<q<<endl;
}*/
};
void Test ::putdata1()
{
cout<<"For Constructor Test(int a, int b)"<<p<<" "<<q<<endl;
}
void Test::putdata2()
{
cout<<"For Constructor Test(Test &i)"<<p<<" "<<q<<endl;
}

void main()
{
Test t1(10, 20);
cout<<"Just testing a copy constructor:: :-)"<<endl;
t1.putdata1();
Test t2(t1);
t2.putdata2();
}
A copy constructor takes a reference to an object of the same class as itself as an
argument.
thank you very much!

i like examples, makes things easier to understand (at least for me ;) )

I think i almost got it now, the only thing i'm still not sure about, is the ampersand (&) in the copy constructor

 
Test(Test &i)


according to main() i give the class t2 the parameter (t1)

 
Test t2(t1);


so it does look like the following in the class "t2", right?

 
Test(Test &t1)


wouldn't this assign the address of t1 to the parameter here? or is the ampersand used here differently?

but in the copy constructor itself, i only use i and not &i. so is it the following?:

1
2
3
4
5
Test(Test &t1)
     {
          p = t1.p; // p=10
          q = t1.q; // p=20
     }


can i manipulate the values further? just like this:

1
2
3
4
5
Test(Test &i)
     {
          p = i.p * 70;
          q = p / i.q;
     }


thank you for your time and help (and patience with me ^^)

greetings from austria
genbatzu~
Last edited on
Hi genbatzu: Greetings from Tampa, Florida!

Yes, the ampersand in C++ is also used for references, which is the case here. Think of a reference as an "always dereferenced pointer." But, you use the structure notation (".") not the pointer notation ("->".)

All of your questions are correct: When you call a class constructor or a function that takes a reference, you don't use the ampersand. But in your copy constructor or a function that takes a reference, you use the ampersand.

You can manipulate "i" in your last example. However, typically when you have a copy constructor or an operator = (), you should make the parameter const:

1
2
3
4
5
6
7
8
9
10

Test( const Test & i )
    {
    p = i.p * 70;   // Valid

    i.p = 0;   // Not valid: i is const!

    }
        /*    Test()    */


Then you couldn't manipulate "i", but in a copy constructor or an operator = () generally shouldn't want to change anything in "i."


Last edited on
The copy constructor is vital for passing arguments by value and when there is dynamically allocated member in the class the default constructor won't suffice. The same applies for the equal operator, you don't want a straight member by member copying process because then you would end up with two pointers to the same spot in memory and changing one would screw over the other.

For the sake of example, look at class A:
1
2
3
4
5
6
7
class A {
	public:
		A()
		{ dynamicMemory = new int; }
	private:
		int* dynamicMemory;
};


Then if we had two instances of class A, say instance1 and instance2, the following statement could become problematic.
 
instance2 = instance1;


Suddenly, instance2.dynamicMemory would be pointing to the same slot in memory as instance1.dynamicMemory, so anytime you changed one of them, it would mess with the other. To fix this, you should overload the assignment operator like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A {
	public:
		A()
		{ dynamicMemory = new int; }
		A& operator=(const A& source);
	private:
		int* dynamicMemory;
};

A& A::operator=(const A& source)  {
	this->dynamicMemory = new int;
	this->dynamicMemory = *(this->dynamicMemory);
	return *this;	
}


I haven't actually coded in C++ in 3-4 months, so if this code is screwy please tell me so I can fix it, it's only done out of vague memory :)
Last edited on
1
2
3
4
5
6
A& A::operator=(const A& source) {
	int x;
	source.dynamicMemory = &x;   // you're pointing to a local object
	source.dynamicMemory = *(this->dynamicMemory);
	return *this;	
}  // 'x' dies here, so dynamicMemory is now a bad pointer 


Also, you're modifying 'source' which is backwards. You should be modifying this.
Last edited on
Thanks, excuse my lack of OOP, I'm more a C guy nowadays :/
Hopefully it should work now!
closed account (zb0S216C)
Just be careful when using copy constructors and dynamically allocated data members. The results will be less than spectacular.

Wazzak
thank you everyone!
you all were a great help for me ^_^
Topic archived. No new replies allowed.