- 1. Пример кода
- 2. Пояснение
- 3. Заключение
Разберём небольшой пример кода, когда вызывается метод у объекта, который инициализирован nullptr .
Пример кода
Нам дан следующий программный код.
#include <iostream> using namespace std; struct X { X* self() { cout << "call method of nullptr" << endl; if (!this) { cout << "object does not exist" << endl; return nullptr; } cout << "object exist" << endl; return this; } }; int main() { X* x = nullptr; if (x->self()) { return 0; } return 0; }
Пояснение
Как вы думаете, упадёт ли программа в данном случае? А если нет, то что будет выведено в консоль?
Как правило программа в большинстве случае падать не будет. Но это неизвестно. Данный код является примером неопределённого поведения, то есть Undefined Behaviour . Поведение программы будет определяться внутренней реализацией компилятора и не даст гарантированного результата. То есть падение программы и исправное выполнение программы являются равнозначно правильными ответами.
Что же произойдёт в случае исправного функционирования программы?
Ответ: В консоль будет выведено следующее сообщение
call method of nullptr object does not exist
То есть метод выполнится как статический метод, как если бы мы обращались к статическому методу класса. Это возможно за счёт того, что известен тип объекта, сигнатура и реализация вызываемого метода. При этом не выполняется обращение к внутренним переменным класса. А проверка на this позволяет удостовериться, существует ли объект. Также можно обойтись и без этой проверки, код всё равно будет выполняться да тех пор, пока не встретится часть кода, которая требует созданного объекта.
Заключение
Тем не менее данный код является примером неопределённого поведения - Undefined Behaviour . Поэтому такие фокусы крайне не рекомендуются при разработке программного обеспечения. Поскольку даже если сейчас код работает, то в следующей версии компилятора это может перестать работать. Поэтому несколько раз подумайте, прежде чем такое писать.