Copy constructor and dynamically allocated array

11,488
//is this object constructed well?
int arr [] = { 16, 2, 7};
Circle a(arr);

The answer is "yes and no": Your constructor does not make a copy of the array, it just copies a pointer to the first element of an array. So if you don't want your Circle class to own the array, you do not need to provide destructor, copy constructor or assignment operator.

But it is more likely that you do want your class to own the array, in which case you need to make a local copy of it and store it. For this to work, you need one extra piece of information: the size of the array, which is completely lost when passed to (and implement the destructor, copy constructor, assignment operator) a function taking a pointer.

Edit since this is an exercise in dynamic allocation in the case where the input array is always size 3, then this is an example of a constructor taking an array:

Circle(int* p)
{
  data = new int[3];
  std::copy(p, p+3, data); // UB if p doesn't point to an array of at least 3 elements
}

You need to call delete[] in the destructor, since you called new[]:

~Circle()
{
    delete [] data;
}

When implementing the assignment operator, consider the copy and swap idiom.

Share:
11,488
Stanimirovv
Author by

Stanimirovv

Wannabe developer with a stupid sense of humour.

Updated on June 04, 2022

Comments

  • Stanimirovv
    Stanimirovv almost 2 years

    I will keep it short and clear - in order to practise dynamically allocated memory, I decided to make a circle in which I will store it's parameters (X and Y of the center and radius length) in a dynamically allocated array. Since the array is dynamically allocated this means that in order to stop a leak I have to implement a constructor. It also means that in order to avoid a couple of other bugs I need to implement a copy constructor and overload the assignment operator. (with pretty much the same code) I think I have implemented the destructor reasonably well. I do need a bit of help with the copy constructor, though.

    #include <iostream>
    
    using namespace std;
    
    class Circle
    {
    private:
        int* data;
    public:
        Circle(){
            cout <<"I am the default constructor" << endl;
            data = NULL;
        }
        Circle(int* p){
            cout <<"I am the set up constructor" << endl;
            data = p;
        }
        ~Circle(){
            cout <<"I am the destructor" << endl;
            delete data;
        }
        Circle& operator=(const Circle& tt1){
            cout << "Overloaded assignment operator reporting in!" << endl;
            if(this != &tt1){
                //free old data
                delete this->data;
                data = new int(3);
               *data = *(tt1.get_data());
                *(arr+1) = *(tt1->get_data()+1);
                *(arr+2) = *(tt1->get_data()+2);
                return *this;
            }
        }
        Circle(const Circle& tt1){
            cout << "I am the copy constructor!" << endl;
            if(this != &tt1){
                //free old data
                delete this->data;
                data = new int(3);
               *data = *(tt1.get_data());
                *(arr+1) = *(tt1->get_data()+1);
                *(arr+2) = *(tt1->get_data()+2);
                return *this;
            }
        }
    };
    
    int main(){
        //is this object constructed well?
        int arr [] = { 16, 2, 7};
        Circle a(arr);
    
        return 0;
    }
    
  • Stanimirovv
    Stanimirovv almost 11 years
    Yes, I do want the class to own the array. Since I am always going to use exactly 3 elements, can I skip passing it ? Also, what would be a correct construction of an object that owns the array?
  • juanchopanza
    juanchopanza almost 11 years
    @Bloodcount if the size is always three, then you probably do not want dynamic allocation. So what are the real constraints?
  • Stanimirovv
    Stanimirovv almost 11 years
    I agree that it is bad design to do it with dynamic memory, however I am right now learning the usage of the copy constructor and even though this isn't a good example I want to see it working (my plan is to implement my own version of a vector a bit later, that is why I am using a dynamically allocated array)
  • juanchopanza
    juanchopanza almost 11 years
    @Bloodcount I added a constructor and a destructor. With the former, you can probably figure out the copy constructor and assignment operator.
  • Stanimirovv
    Stanimirovv almost 11 years
    I think I can figure the rest out on my own. Thank you!
  • awesoon
    awesoon almost 11 years
    Just a note: Not necessary to check pointer for NULL before deleting.
  • jie
    jie almost 11 years
    I'm not sure what you say is correct. But thank you very much.
  • awesoon
    awesoon almost 11 years
    It is. You could read about it in § 5.3.5 (2, 6, 7) C++ Standard
  • juanchopanza
    juanchopanza almost 11 years
    There is no need to check for self-assignment in a copy constructor, it is debatable whether it is a good idea in an assignment operator (it can silently hide buggy code), there is no need for get_data, and you can use std::copy to copy the elements of one Circle to the other.
  • jie
    jie almost 11 years
    get_data is redundant, but this is just a practice, use many ways I think is godd, are you agree me? Thank you for your advice. @juanchopanza