// example on constructors and destructors
#include <iostream>
usingnamespace std;
class CRectangle {
int *width, *height;
public:
CRectangle (int,int);
~CRectangle ();
int area () {return (*width * *height);}
};
CRectangle::CRectangle (int a, int b) {
width = newint;
height = newint;
*width = a;
*height = b;
}
CRectangle::~CRectangle () {
delete width;
delete height;
}
int main () {
CRectangle rect (3,4), rectb (5,6);
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
return 0;
}
According to the text a destrucor is called when an object is destroyed. So, first we call CRectangle with rect(3,4) but the ~CRectangle () function will not be called because the object is still valid. After the second call with rectb(5,6) the old values will be erased by ~CRectangle because they are destroyed by the new values? So, in effect only rect(3,4) will be erased? A further question would be why one uses pointers in this example? Is it necessary? It seems overly convoluted to me.
Thanks in advance for some answers to my ongoing stupid questions.
"A destructor is another type of special member function. "
It is called implicitly when an object is destroyed. If you want to understand more about this, put a print function in there, run the program and see when its called.
in other words, when an object needs to be deleted , losing scope, etc the destructor will be called.
For good practice when you allocate dynamic memory in your program it is good practice to delete (destroy) any unused memory
For instance, if you are doing dynamic array allocation, it is good practice to put your delete code to destroy the allocated memory after its destructor is called.
According to the text a destrucor is called when an object is destroyed. So, first the we call CRectangle with rect(3,4) but the ~CRectangle () function will not be called because the object is still valid. After the second call with rectb(5,6) the old values will be erased by ~CRectangle because they are destroyed by the new values? So, in effect only rect(3,4) will be erased?
No, the second call will not erase the old values. They're not old values at all. There are two instances of the class here, each with their own destructor. They will run independently when the object is destroyed.
1 2 3 4 5 6 7
int main()
{
CRect recta, rectb;
// Do stuff
// Destructors for both CRect objects called here
}
Alternatively, if you had dynamically allocated CRects:
1 2 3 4 5 6 7 8 9 10 11 12 13
int main()
{
CRect* recta = new CRect;
CRect* rectb = new CRect;
// Do stuff
delete recta; // recta's destructor runs here
// Do stuff
delete rectb; // rectb's destructor runs here
}
Probably because there is generally not much to do in a Constructor if you don't have heap-allocated variables in your class.
It's generally a good idea to have each class take care of its own memory. It's also generally a good idea to check, and double check, that every "new'd" variable is deleted, and only those are deleted. If there is a chance that a CRect object is created without allocating memory, make sure not to call the delete on this!
E.g.:
1 2 3 4 5 6 7 8 9
class CRectangle {
CRectangle (int,int);
CRectangle (void) { } // 'Empty constructor'
}
int main() {
CRectangle myRect;
return 0;
// Here, an error will be thrown, because myRect's deconstructor will (try to) delete uninitialized memory.
}
Sometimes, the empty constructor is required (e.g.: if you want to make an array of CRectangles). In those cases, make sure the deconstructor checks. (e.g.:if (width != nullptr) delete width; )
No, the second call will not erase the old values. They're not old values at all. There are two instances of the class here, each with their own destructor. They will run independently when the object is destroyed.
My problem is that ~CRectangle comes before the calculation of the area:
1 2 3
CRectangle (int,int);
~CRectangle ();
int area () {return (*width * *height);