views:

3271

answers:

6

Hi, I am studying for my midterm exam. There is going to be a question about setting up an array dynamically, and maybe doing a copy constructor, a destructor and overloading the assignment operator. Can you please verify if I am correct. Also I don't understand what overloading the assignment operator means. Can you help me out with this?

class A
{
int* myArray;   //basically I created a pointer called myArray, 
A()             //are my copy constructors correct? A(), and A(int size)?
{
    myArray = 0;
}
A(int size)
{
    myArray = new int[size];
}
~A()             // I think my destructor is correct
{
    delete [] myArray;
}

Can you check my code please? Also how do I overload assignment operator?

Thanks in advance.

A: 

The copy constructor is used for creation of object based on another's instance of the same type. You don't have such. You can define it using code like this:

A(const A &other)
{
   myArray = new int[other._size];
   _size = other._size;
   memcpy(myArray, other.myArray, sizeof(int) * _size);
}

You should change your class, so it will store _size of array, you also need to change visibility of your constructors and destructor to public.

The overloaded assignment operator should look like this:

const A &operator=(const A &other)
{
   if(this == &other) return *this; // handling of self assignment, thanks for your advice, arul.
   delete[] myArray; // freeing previously used memory
   myArray = new int[other._size];
   _size = other._size;
   memcpy(myArray, other.myArray, sizeof(int) * _size);
   return *this;
}

You also can add a check of equality of array sizes in this assignment operator, so you will reuse your dynamic array without unnecessary reallocations of memory.

Dmitriy Matveev
The assignment operator should also handle self-assignment.
arul
In general, it is a good idea, to use copy-and-swap idiom in assignment operators - http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-and-swap
Paulius Maruška
A: 

Partial answer: overloading a function involves creating different versions of that function which accept different numbers or kinds of arguments. So overloading the assignment operator would involve creating several functions for the assignment operator which allow you to assign objects of various types to a variable of type A.

David Zaslavsky
+3  A: 

You have correctly defined 2 overloaded constructors and a destructor.

However, you haven't defined an explicit copy constructor properly.

Normally the compiler will generate one for you, and this is called an implicit copy constructor.

The problem with the auto-generated implicit copy constructor in your particular case is that it will only perform a shallow copy of myArray, where it shares the same pointer value but hasn't allocated its own section of memory for myArray.

This means if you delete myArray in the original object, it will affect the copy which is most likely not what you want.

Defining an explicit copy constructor like this will help:

A(const A& copy)
  : _size(copy.size), myArray(new int[copy.size]) 
{
    // #include <algorithm> for std::copy
    std::copy(copy.data, copy.data + copy.size, data);
}

(Source: Copied from Wikipedia)

If you define the copy constructor like this, you should not need to overload the assignment operator. If you create a new object, and assign it to the first object you created, you will successfully create an independent copy of the first object.

Edit: From this article:

The copy assignment operator differs from the copy constructor in that it must clean up the data members of the assignment's target (and correctly handle self-assignment) whereas the copy constructor assigns values to uninitialized data members.

LeopardSkinPillBoxHat
A: 

Read a book. Or, at the very least, show us what you have done for your self. Next time, before posting, read the FAQ Lite at least.

FWIW, read chapters 10, 12 and 13 from the FAQ Lite.

dirkgently
+1  A: 

when dealing with object copy and dynamic memory allocation it's a good idea to use a swap helper function

A(const A& other)
    : myArray(0)
    , _size(0)
{
   if(this != &other) {
      A my_tmp_a(other._size);
      std::copy(&other[0], &other[other._size], &my_tmp_a[0]=;
      swap(my_tmp_a);
   }
}

const A& operator=(const A& other)
{
   if(this == &other) return *this;
   A my_tmp_a(other._size);
   std::copy(&other[0], &other[other._size], &my_tmp_a[0]=;
   swap(my_tmp_a);
   return *this;
}

void swap(const A& other) {
   int* my_tmp_array = this.myArray;
   this.myArray = other.myArray;
   other.myArray = my_tmp_array;
   int my_tmp_size = this._size;
   this._size = other._size;
   other._size = my_tmp_size;
}
thrantir
+1 for the use of copy and swap in assignment operator.
Paulius Maruška
Non need to slow down the execution with a test what will be useless 99.999% of the time. The copy-and-swap idiom is more than enough.
Luc Hermitte
A: 

Please make sure define three functions when you want to define one of them. Its called all or none rule They are: 1) copy constructor. 2) assignment operator. 3) destructor.