При объявлении переменной в стеке существует два основных соображения по сравнению с кучей - контроль времени жизни и управление ресурсами.
Распределение в стеке работает очень хорошо, когда у вас есть жесткий контроль над временем жизни объекта. Это означает, что вы не собираетесь передавать указатель или ссылку на этот объект в код вне области локальной функции. Это означает, что нет никаких параметров, нет COM-вызовов, нет новых потоков. Довольно много ограничений, но вы правильно очищаете объект при нормальном или исключительном выходе из текущей области (хотя, возможно, вы захотите прочитать правила раскрутки стека с помощью виртуальных деструкторов). Самый большой недостаток размещения стека - размер стека обычно ограничен 4K или 8K, поэтому вы можете быть осторожны с тем, что на него надето.
Распределение кучи с другой стороны потребует очистки экземпляра вручную. Это также означает, что у вас есть много свободы в управлении временем жизни экземпляра. Это необходимо сделать в двух сценариях: а) вы собираетесь вывести этот объект из области видимости; или б) объект слишком велик, и размещение его в стеке может вызвать переполнение стека.
Кстати, хорошим компромиссом между этими двумя является выделение объекта в куче и выделение умного указателя на него в стеке. Это гарантирует, что вы не тратите впустую драгоценную память стека, и в то же время получаете автоматическую очистку при выходе из области.