O RAII trata parcialmente de decidir quando um objeto se torna responsável por sua própria limpeza - a regra é que o objeto se torna responsável se e quando a inicialização do construtor for concluída. A simetria de inicialização e limpeza, construtor e destruidor, significa que os dois têm laços estreitos entre si.
Um ponto do RAII é garantir a segurança das exceções - que o aplicativo permaneça autoconsistente quando as exceções forem lançadas. À primeira vista, isso é trivial - quando uma exceção faz com que um escopo saia, as variáveis locais nesse escopo precisam ser destruídas.
Mas o que acontece se o lançamento da exceção ocorrer dentro de um construtor?
Bem, o objeto não foi totalmente construído, portanto não pode ser destruído com segurança. O construtor deve ter blocos de tentativa, conforme necessário, para garantir que todas as limpezas necessárias sejam feitas antes que a exceção seja propagada. Depois que a exceção se propagar fora do escopo em que o objeto foi construído, não haverá chamada de destruidor, porque o objeto não foi construído em primeiro lugar.
Considere, em particular, os construtores para dados de membros dentro do objeto que estão sendo destruídos. Se um deles lançar uma exceção, seu código principal do construtor não será executado - mas algum código que forme uma parte implícita desse construtor terá. Quaisquer membros que foram construídos com sucesso serão automaticamente destruídos. Quaisquer membros que não foram construídos (incluindo o que lançou a exceção) não são.
Então, basicamente, a RAII é uma política que garante que tudo que for totalmente construído será destruído em tempo hábil, principalmente na presença de lançamentos de exceção, e que qualquer objeto seja totalmente construído ou não é (não há meio- objetos construídos que você não sabe como limpar com segurança). Os recursos alocados também são liberados. E muito do trabalho é automatizado, para que o programador não precise se preocupar muito com isso.