Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ copy constructor for class with dynamically allocated array

Just starting on C++ (a few days now), I come with C background.

I have a class that holds, mainly, an a pointer to an int array with the following code:

class Array
{
private:
    int * _arr;
    int _size;
public:
    Array();
    Array(int size);
    Array(const Array& obj);  // copy constructor
    ~Array();
    void readInValues();
    void mult(int num);
    void add(int num);
    void printArray();
};

_arr is a pointer to an int array, when creating a new instance using the copy constructor I would to create a new int array on the heap (I think). In the copy constructor:

Array::Array( const Array & obj )
{
    _arr = new int[_size];

    for(int i=0;i<_size;i++)
        *_arr[i] = *obj._arr[i];
}

The 1st thing I do is allocate memory for the new array (_size is a primitive type so being copied automatically as far as I understood). The next thing I would like to do is copy the array itself using a loop. This parts fails the compilation saying illegal indirection. I am not sure why...

like image 948
user34920 Avatar asked Mar 27 '26 13:03

user34920


1 Answers

This:

Array::Array( const Array & obj )
{
    _arr = new int[_size];

    for(int i=0;i<_size;i++)
        *_arr[i] = *obj._arr[i];
}

could be this:

Array::Array( const Array & obj )
    : _arr(obj._size ? new int[obj._size] : nullptr)
    , _size(obj._size)
{
    if (_arr)
        std::copy(obj._arr, obj._arr+_size, _arr);
}

Specifically, note the use of the initializer list. Other things worth mentioning:

  1. Don't use identifiers with leading underscores. Besides making the code a royal pain to read, you can quickly find yourself using identifiers that are reserved by the implementation. That isn't the case here, but I'm willing to bet that wasn't by intent.

  2. You also need an assignment operator to fulfill the Rule of Three. Thankfully, a decent copy constructor makes that trivial.

  3. Don't do any of this. This is why, with great wailing and much gnashing of teeth in design decisions, the almighty C++ standards committees of years-gone-by have so-chosen to bless us with std::vector<>. If you're doing this to learn, good. What you'll eventually learn is how rarely you need to once you embrace the standard library and all its guilty pleasures.

If this is intended as a learning exercise, kudos, and blissfully ignore (3) above. For (2), you can use the copy/swap idiom now that you have a reasonable copy-ctor:

Array& Array::operator =(Array obj) // value-param intentional
{
    std::swap(_arr, obj._arr);
    std::swap(_size, obj._size);
    return *this;
}

Best of luck.

like image 96
WhozCraig Avatar answered Mar 29 '26 03:03

WhozCraig



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!