Во всех четырех случаях поведение не определено;поэтому именно то, что происходит, зависит от того, что делает ваш компилятор перед лицом неверного ввода.
Компилятор может попытаться диагностировать проблему, чтобы выдать предупреждение;это легко сделать для строки 1 и труднее для других строк, что объясняет, почему вы видите только предупреждение для строки 1.
При вызове виртуальной функции из конструктора компилятор знает, какая перегрузкадолжен быть вызван, и поэтому он может генерировать статический вызов.Вот почему вы получаете сообщение об ошибке в строке 2 и строке 4.
В строке 3 компилятор, должно быть, решил, что слишком сложно определить, может ли он генерировать статический вызов, поэтому он сгенерировал динамическийпозвони вместо.Отслеживать значение переменной довольно сложно, чем понять, что временный указатель должен ссылаться на this
, и часто вообще не представляется возможным.Вот почему вы получаете ошибку во время выполнения.
Конечно, все это неопределенное поведение, которое может меняться от компилятора к компилятору или в соответствии с фазой луны.
Если бы у функции была реализация, то было бы правильно назвать ее статически , как Base::bar()
или bptr->Base::bar()
.Динамический вызов будет по-прежнему давать неопределенное поведение.