Ответ 1
Я все равно буду следовать общему правилу для классов, которые должны быть выведены:
Предоставить либо общедоступный виртуальный деструктор, либо защищенный не виртуальный деструктор
Причина в том, что вы не можете контролировать все виды использования, и это простое правило означает, что компилятор будет отмечать, если вы попытаетесь выполнить delete
через неправильный уровень в иерархии. Учтите, что shared_ptr
не гарантирует, что он вызовет соответствующий деструктор, только то, что он вызовет деструктор статического типа, который использовался как аргумент:
base* foo();
shared_ptr<base> p( foo() );
Если base
имеет общедоступный не виртуальный деструктор, а foo
возвращает тип, полученный из base
, то shared_ptr
не сможет вызвать правильный деструктор. Если деструктор base
является виртуальным, все будет хорошо, если он защищен, компилятор скажет вам, что там есть ошибка.