If (! this) {return false; }

Я наткнулся на этот фрагмент кода, который кажется мне полным, но бывает, что this - null. Я просто не понимаю, как это может быть null

он находится внутри обычного вызова метода, такого как

myObject->func();

внутри MyObject::func() имеем

if (!this) { return false; }

есть ли способ, чтобы первая строка выбрала NullPointerException вместо того, чтобы идти внутрь метода null (?)?

Ответ 1

Если у вас есть:

MyObject *o = NULL;

o->func();

Что будет дальше, зависит от того, является ли func виртуальным. Если это так, то он сработает, потому что ему нужен объект для получения vtable. Но если он не является виртуальным, вызов переходит с указанным указателем равным NULL.

Я считаю, что стандарт говорит, что это "поведение w90 > ", поэтому все может случиться, но типичные компиляторы просто генерируют код, чтобы не проверять, является ли указатель NULL. Некоторые известные библиотеки полагаются на поведение, которое я описал: MFC имеет функцию, называемую чем-то вроде SafeGetHandle, которая может быть вызвана нулевым указателем и возвращает в этом случае NULL.

Возможно, вы захотите написать многократную вспомогательную функцию:

void CheckNotNull(void *p)
{
    if (p == NULL)
        throw NullPointerException();
}

Затем вы можете использовать это в начале функции для проверки всех своих аргументов, включая this:

CheckNotNull(this);

Ответ 2

Способ улавливания подобных ошибок (по дизайну) использует класс-указатель-обертка (похожий на shared_ptr), который бросает на создание с аргументом нулевого указателя. Он может также бросаться, когда разыменовывается, но немного поздно - лучше, чем ничего, я думаю.

Ответ 3

if(this == null)
   throw new NullPointerException;
if(!this)
   return false;

Ответ 4

Возможно, для this будет null. Я подозреваю, что этот код пытается (плохо) обнаруживать состояние гонки, когда объект еще не завершен, инициализируется или был удален.

Ответ 5

(this == NULL) - это поведение undefined в соответствии со стандартом. Я думаю, вы должны удалить эту проверку:)

Предположим, что мы делаем следующий вызов:

((CSomeClass*) 0)->method();

Поведение уже undefined, так зачем беспокоиться о выполнении этого == NULL в методе CSomeClass::??

Редакция: Предположим, что ваш компилятор будет обрабатывать (0 == this), если вы не используете переменные-члены, но где он найдет указатель виртуальной таблицы? В этом случае ваш класс не может использовать полиморфизм.

Ответ 6

этот указатель может стать нулевым в таких случаях:

class Test
{

public:
    bool f();

private:
    int m_i;
};


bool Test::f()
{
    if(!this)
    {
        return false;
    }

    m_i = 0;
    return true;

}


int main(int argc, char **argv)
{
    Test* p = new Test;
    delete p;
    p = NULL;

    p->f();
}

Я предполагаю, что кто-то быстро взломал, чтобы избежать исключения нарушения доступа.

Ответ 7

this == null должен произойти только в том случае, если вы вызываете метод на удаленном объекте, или если что-то записывает в память, что оно не должно (и, в частности, переписывать объект в этом указателе).

Вы должны исследовать, что действительно неправильно с вашим кодом, а не пытаться обойти его следующим образом.