Ответ 1
Опять же, Undefined Поведение. Ваша программа имеет несколько определений для деструктора Foo
, что означает, что оно нарушает ODR. Программа неправильная, и все может случиться.
Почему компоновщик не забирает его? Когда функция определена внутри определения класса, она неявно inline
. Компиляторы обычно отмечают эти функции как "слабые символы". Затем компоновщик получает все единицы перевода и пытается разрешить символы. Слабые символы будут удалены компоновщиком, если необходимо (т.е. Если символ уже определен где-то в другом месте).
Как и фактический вывод программы, похоже, что компилятор фактически не ввел вызов конструктору и, таким образом, отправил во время выполнения символ, оставленный компоновщиком (не слабым)
Почему линкер позволяет иметь повторяющиеся методы?
Поскольку все (но не более одного) являются слабыми символами (т.е. inline
)
Почему в этом случае печатается неправильная ~ Foo()?
Поскольку вызов не был вложен, а компоновщик сбросил слабый символ