Мне дали следующий вопрос:
class A
{
public:
void fun()
{
std::cout << "fun" << std::endl;
}
};
A* a = NULL;
a->fun();
Что произойдет, когда этот код будет выполнен, и почему?
Мне дали следующий вопрос:
class A
{
public:
void fun()
{
std::cout << "fun" << std::endl;
}
};
A* a = NULL;
a->fun();
Что произойдет, когда этот код будет выполнен, и почему?
Это поведение undefined, поэтому все может случиться.
Возможным результатом будет то, что он просто печатает "fun"
, поскольку метод не получает доступа к каким-либо переменным-членам объекта, на который он вызван (память, в которой объект, предположительно, живет, не нуждается в доступе, поэтому доступ нарушения не обязательно происходят).
По стандарту это поведение undefined и, следовательно, очень плохое. В действительности большинство платформ программирования (как для X86, так и для нескольких других архитектур) будет работать нормально.
Почему? Рассмотрим, как функции класса реализованы на С++. Это не виртуальная функция, поэтому это может быть статический вызов известного адреса. В сборке x86 мы можем видеть это как
mov A, 0
mov ecx, A
call a__fun
поскольку a__fun не требует данных экземпляра, даже если он получает нуль этого указателя, ничего не произойдет.
Все еще дерьмовый код, и любой компилятор будет кричать, но он может работать.
Наиболее вероятное поведение на большинстве современных компьютеров заключается в том, что он будет работать и печатать "весело", потому что:
fun()
не является виртуальным, поэтому нет необходимости ссылаться на vtable для вызова fun()
fun()
никогда не обращаться к переменным-члену в A
, поэтому ему не нужно разыгрывать
указатель null this
.Мы не можем знать, что будет. Все может случиться, потому что программа раскрывает поведение undefined. См. Выполняет ли вызов функции-члена в случае null-экземпляра поведение undefined?.
Я пробовал несколько раз, все время вывод идет "весело", потому что функция fun
не зависит от экземпляра a
. при вызове a->fun();
a
указывает на 0, поэтому это поведение undefined, но в большинстве компиляторов не должно быть сбоя.