This is indeed the way it should be - the destructor declared virtual in the base class.
It is to ensure when a Base is to be destroyed, it is properly done - the destructor of Derived is called first, then the dtor of Base.
Now, since you haven't provided a dtor for Derived, the default dtor is called.
If you mark a method as virtual in the bass class, it's not necessary that you also mark it as virtual in the derived class (but I think it's a good idea to do so, it makes the code easier to understand).
Yes, you can try making your destructors display something. You would see that the dtor of the derived class is not called if you don't say virtual in the base.
I don't have much idea what's happening behind =\ maybe the memory isn't handled properly...
class B
{
protected:
int i;
public:
B ( int i ) : i ( i ) {} // base constructor
};
class D : public B
{
public:
D ( int i ) : B ( i ) {} // derived constructor calling the base one
D ( something ) // other derived constructor not calling the base constructor
{
//...
}
};