Hi All

We all have read a lot about utility of copy constructor.

I have a simple question .Consider the code below. Is it ok to directly copy one object's content onto other ?

Class A {

......

};

main ()
{

  A * obj_1=new A();
      
  // Next the obj_1 variables are initialized

  A * obj_2=new A();
  
//Make a copy of obj_1
  *obj_2=*obj_1;          ---> Is this OK ?

Thanks
Varun

Maybe, and maybe not. Depends on the class. The compiler will generate a default copy constructor which copies only POD (Plain Old Data)-- contents of pointers and STL containers are not copied.

Is it ok to directly copy one object's content onto other ?

The problem is aliasing. For example, if any of your data members are pointers then an explicit copy constructor is required to make a deep copy of the object. Otherwise the pointers from two objects will point to the same block of memory:

#include <iostream>
#include <ostream>

class DynamicArray {
    int *_array; // Non-shallow type; suitable explicit copy constructor required
    int _size;
public:
    DynamicArray(int size): _size(size) { _array = new int[size]; }
    ~DynamicArray() { delete[] _array; }

    int& operator[](int i) { return _array[i]; }

    friend std::ostream& operator<<(std::ostream& out, const DynamicArray& da)
    {
        out<<'(';

        for (int i = 0; i < da._size; i++) {
            out<< da._array[i];

            if (i < da._size - 1)
                out<<',';
        }

        return out<<')';
    }
};

int main()
{
    DynamicArray arr1(5);

    for (int i = 0; i < 5; i++)
        arr1[i] = i;

    std::cout<< arr1 <<'\n';

    DynamicArray arr2 = arr1;

    for (int i = 0; i < 5; i++)
        arr2[i] = i + 10;

    std::cout<< arr1 <<'\n'<< arr2 <<'\n';
}

Notice how altering arr2 also changes the contents of arr1. That's because _array is an alias for the same block of memory. Both objects refer to the same underlying array. In this case a copy constructor is necessary to make a deep copy of the pointed to memory:

#include <iostream>
#include <ostream>

class DynamicArray {
    int *_array; // Non-shallow type; suitable explicit copy constructor required
    int _size;
public:
    DynamicArray(int size): _size(size) { _array = new int[size]; }
    DynamicArray(const DynamicArray& da) { fill_array(da._array, da._size); }
    DynamicArray& operator=(const DynamicArray& da) { fill_array(da._array, da._size); }
    ~DynamicArray() { delete[] _array; }

    int& operator[](int i) { return _array[i]; }

    friend std::ostream& operator<<(std::ostream& out, const DynamicArray& da)
    {
        out<<'(';

        for (int i = 0; i < da._size; i++) {
            out<< da._array[i];

            if (i < da._size - 1)
                out<<',';
        }

        return out<<')';
    }
private:
    void fill_array(int *array, int size)
    {
        _array = new int[size];

        for (int i = 0; i < size; i++)
            _array[i] = array[i];

        _size = size;
    }
};

int main()
{
    DynamicArray arr1(5);

    for (int i = 0; i < 5; i++)
        arr1[i] = i;

    std::cout<< arr1 <<'\n';

    DynamicArray arr2 = arr1;

    for (int i = 0; i < 5; i++)
        arr2[i] = i + 10;

    std::cout<< arr1 <<'\n'<< arr2 <<'\n';
}

So is your example okay? Maybe. It depends on how the class is defined, and your expectations for the result as to whether the copy is safe or not.

Maybe I'm confused, but isn't this an example of the assignment operator, not the copy constructor? Wouldn't the copy constructor be more like this:

Class A {

......

};

main ()
{

  A * obj_1=new A();
      
  // Next the obj_1 variables are initialized

  //Make a copy of obj_1
  A * obj_2=new A(*obj_1);

???
Either way, it is okay to do what you are asking about as long as you have the proper constructor and/or operator(s) defined in your class. Just make sure that if you have pointers in your class, you have both. They would both be written the same way.

Edited 5 Years Ago by Fbody: n/a

This article has been dead for over six months. Start a new discussion instead.