- 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 . Тому такі фокуси вкрай не рекомендуються при розробці програмного забезпечення. Оскільки навіть якщо зараз код працює, то в наступній версії компілятора це може перестати працювати. Тому кілька разів подумайте, перш ніж таке писати.