Деструктор не будет запущен, если в конструкторе возникнет исключение.
Он будет запущен при необходимости (если где-то обрабатывается исключение), если исключение возникает в другом методе, как в вашем примере. Но поскольку программа завершается, вызывать деструктор здесь не нужно, и поведение зависит от компилятора ...
Идея RAII
заключается в том, что конструктор распределяет ресурсы, а деструктор освобождает их. Если в конструкторе возникает исключение, не существует простого способа узнать, какие ресурсы были выделены, а какие нет (это зависит от точного места в конструкторе, где произошло исключение). Вы также должны помнить, что если конструктор дает сбой, единственный способ сказать его вызывающей стороне - вызвать исключение выделенной памяти и (либо разматывание стека, либо выделение памяти в куче), как если бы он никогда не выделялся .
Решение очевидно: если внутри конструктора может возникнуть какое-либо исключение, вы должны перехватить его и при необходимости освободить выделенные ресурсы. На самом деле это может быть некоторый дублированный код с деструктором, но это не большая проблема.
В деструкторе вы не должны вызывать исключения, так как это может привести к большим проблемам с размоткой стека.
В любом другом методе используйте исключения по своему усмотрению, но не забывайте где-нибудь их обрабатывать. Необработанное исключение может быть хуже, чем не исключение вообще. Я знаю о некоторых программах, которые не обрабатывают исключения для некоторых незначительных ошибок ... и аварийно завершают работу при ошибках, которые должны выдавать только предупреждение.