Evgenii Legotckoi
Evgenii Legotckoi21 липня 2020 р. 02:31

Виклик методу на nullptr

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

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
B
  • Bogdannn
  • 28 березня 2024 р. 07:21

C++ - Тест 002. Константы

  • Результат:16бали,
  • Рейтинг балів-10
B
  • Bogdannn
  • 28 березня 2024 р. 07:15

C++ - Тест 001. Первая программа и типы данных

  • Результат:46бали,
  • Рейтинг балів-6
FL

C++ - Тест 006. Перечисления

  • Результат:80бали,
  • Рейтинг балів4
Останні коментарі
k
kmssr09 лютого 2024 р. 07:43
Qt Linux - Урок 001. Автозапуск програми Qt під Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко05 лютого 2024 р. 14:50
Qt WinAPI - Урок 007. Робота з ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 грудня 2023 р. 23:30
Boost - статичне зв&#39;язування в проекті CMake під Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 грудня 2023 р. 21:38
Boost - статичне зв&#39;язування в проекті CMake під Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik19 грудня 2023 р. 10:01
Qt/C++ - Урок 056. Підключення бібліотеки Boost в Qt для компіляторів MinGW і MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Тепер обговоріть на форумі
P
Pisych27 лютого 2023 р. 17:04
Как получить в массив значения из связанной модели? Спасибо, разобрался:))
AC
Alexandru Codreanu20 січня 2024 р. 00:57
QML Обнулить значения SpinBox Доброго времени суток, не могу разобраться с обнулением значение SpinBox находящего в делегате. import QtQuickimport QtQuick.ControlsWindow { width: 640 height: 480 visible: tr…
BlinCT
BlinCT27 грудня 2023 р. 21:57
Растягивать Image на парент по высоте Ну и само собою дял включения scrollbar надо чтобы был Flickable. Так что выходит как то так Flickable{ id: root anchors.fill: parent clip: true property url linkFile p…
Дмитрий
Дмитрий10 січня 2024 р. 17:18
Qt Creator загружает всю оперативную память Проблема решена. Удалось разобраться с помощью утилиты strace. Запустил ее: strace ./qtcreator Начал выводиться весь лог работы креатора. В один момент он начал считывать фай…
Evgenii Legotckoi
Evgenii Legotckoi12 грудня 2023 р. 19:48
Побуквенное сравнение двух строк Добрый день. Там случайно не высылается этот сигнал textChanged ещё и при форматировани текста? Если решиать в лоб, то можно просто отключать сигнал/слотовое соединение внутри слота и …

Слідкуйте за нами в соціальних мережах