throwing an exception in the constructor comes to mind, in which case the destructor isn't called
Of course it is not called -- the object has failed to construct. There is no object. You cannot call a destructor on nothing. Now if some data member has been constructed but the call constructor failed, destructors for such members will be called.