Ah, you're throwing from the constructor of B. That changes things. If you throw from a constructor... well, things are different. Here's a page on it that goes into quite some detail:
http://www.gotw.ca/gotw/066.htm
Suffice to say that in your test case, because the A part of the object got constructed fully, it then got destructed fully when the exception was thrown. If you throw from a constructor, the object (as Herb Sutter discusses at length) effectively never comes into being.
Try this code. I took out the f() function and just had the constructor/destructor announce themselves and give their own object's memory location, so you can easily see which object is being destroyed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
#include <iostream>
using namespace std;
class A
{
public:
A(int i)
{
std::cout << "A construction, address is " << this << '\n';
}
~A()
{
std::cout << "A destruction, address is " << this << '\n';
}
};
class B:public A
{
public:
B(int i=0):A(i)
{
std::cout << "B construction, address is " << this << '\n';
}
~B()
{
std::cout << "B destruction, address is " << this << '\n';
}
};
B b(1);
int main()
{
try
{
A *a=new B(-5);
throw 0;
}
catch (int e)
{
printf("Exc \n");
}
return 0;
}
|
In this code, the exception is not thrown from the constructor and as you can see, the object created with new is not then destroyed, as you expected.
The game changed when you threw from the constructor.