0

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

4
Contributors
3
Replies
4
Views
6 Years
Discussion Span
Last Post by Fbody
0

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.

1

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.

0

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 by Fbody: n/a

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.