If the constructor allocates memory and then throws an exception (or calls a function that throws an exception) then you will have leaked the memory. The destructor for the object does not get called (because the destructor can not know how much of the object was constructed) however the destructor for any of its bases does get called.
What this means is that you have to be very careful about what you do in constructors, in many ways you have to write them in much the same way as you used to have to write C code, supper defensively catching all errors. In practice this means that you have to ensure your constructor works or that you have handled memory clean up yourself.
For that reason in our company coding standards constructors are supposed to be simple doing the minimum to put the object in a known state.
Note that it is valid to throw an exception from a constructor you just have to be careful how you do it. In fact in some cases it is essential, if you fail to allocate memory in the constructor that the program requires then your only way to indicate the error is to throw an exception.
In the case you give then following the allocation of data if an exception occurs you need to catch it, delete your data and rethrow the exception.
-
Example::Example()
-
{
-
try
-
{
-
// Allocate memory for member variables
-
member1 = new int;
-
member2 = new int;
-
-
function(); // Call a function that may throw an exception
-
}
-
catch(std::exception& e)
-
{
-
// And exception occured, clean up this object and rethrow
-
delete member1;
-
delete member2;
-
-
throw; // Throw by itself rethrows the current exception
-
}
-
}
-
Note that you should never allow a destructor to throw an exception. This is because destructors can often get called while an exception is in progress and the system can not deal with nest exceptions so it just aborts your program.
Also note that you should never call a virtual function from a constructor, you can not be sure the object is fully constructed and until it is fully constructed the vtable used to call virtual functions may not have the correct pointers in it.