Copy constructor and dynamically allocated array
//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.
Comments
-
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 almost 11 yearsYes, 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 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 almost 11 yearsI 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 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 almost 11 yearsI think I can figure the rest out on my own. Thank you!
-
awesoon almost 11 yearsJust a note: Not necessary to check pointer for
NULL
before deleting. -
jie almost 11 yearsI'm not sure what you say is correct. But thank you very much.
-
awesoon almost 11 yearsIt is. You could read about it in § 5.3.5 (2, 6, 7) C++ Standard
-
juanchopanza almost 11 yearsThere 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 usestd::copy
to copy the elements of oneCircle
to the other. -
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