Проверка, если это является пустым

Мне нравится использовать OrderedBag и OrderedSet классы в PowerCollections как приоритетные очереди.

60
задан user156144 25 September 2010 в 04:45
поделиться

5 ответов

Имеет ли смысл когда-либо проверять это == null? Я обнаружил это во время проверки кода.

В стандартном C ++ это не так, потому что любой вызов нулевого указателя уже является неопределенным поведением, поэтому любой код, основанный на таких проверках, является нестандартным (нет гарантии, что проверка будет даже выполняться).

Обратите внимание, что это верно и для невиртуальных функций.

Однако некоторые реализации разрешают this == 0 , и, следовательно, библиотеки, написанные специально для этих реализаций, будут иногда использую это как хитрость. Хорошим примером такой пары является VC ++ и MFC - я не помню точный код, но отчетливо помню, как видел if (this == NULL) где-то в исходном коде MFC.

Он также может использоваться в качестве средства отладки, потому что в какой-то момент в прошлом этот код получил this == 0 из-за ошибки в вызывающей программе, поэтому была вставлена ​​проверка для обнаружения будущие экземпляры этого. Однако утверждение было бы более разумным для таких вещей.

Если this == null, это означает, что объект удален.

Нет, это не значит. Это означает, что метод был вызван для нулевого указателя или ссылки, полученной из нулевого указателя (хотя получение такой ссылки уже является UB). Это не имеет ничего общего с delete и не требует, чтобы какие-либо объекты этого типа когда-либо существовали.

Однако утверждение было бы более разумным для таких вещей.

Если this == null, это означает, что объект удален.

Нет, это не значит. Это означает, что метод был вызван для нулевого указателя или ссылки, полученной из нулевого указателя (хотя получение такой ссылки уже является UB). Это не имеет ничего общего с delete и не требует, чтобы какие-либо объекты этого типа когда-либо существовали.

Однако утверждение было бы более разумным для таких вещей.

Если this == null, это означает, что объект удален.

Нет, это не значит. Это означает, что метод был вызван для нулевого указателя или ссылки, полученной из нулевого указателя (хотя получение такой ссылки уже является UB). Это не имеет ничего общего с delete и не требует, чтобы какие-либо объекты этого типа когда-либо существовали.

75
ответ дан 24 November 2019 в 17:46
поделиться

FWIW, я использовал отладочные проверки для (this! = NULL) в утверждениях, которые раньше помогали обнаруживать дефектный код. Не то чтобы код обязательно зашел слишком далеко без сбоя, но на небольших встроенных системах, не имеющих защиты памяти, утверждения действительно помогли.

В системах с защитой памяти ОС обычно сталкивается с нарушением доступа если вызывается с указателем NULL this , поэтому утверждение this! = NULL будет меньше. Однако см. Комментарий Павла, почему это не обязательно бесполезно даже в защищенных системах.

6
ответ дан 24 November 2019 в 17:46
поделиться

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

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

27
ответ дан 24 November 2019 в 17:46
поделиться

Скорее всего, ваш метод (может варьироваться в зависимости от компилятора) сможет работать, а также сможет возвращать значение. Пока он не обращается ни к каким переменным экземпляра. Если он попытается это сделать, произойдет сбой.

Как указывали другие, вы не можете использовать этот тест, чтобы увидеть, был ли объект удален. Даже если бы вы могли, это не сработало бы, потому что объект может быть удален другим потоком сразу после теста, но до того, как вы выполните следующую строку после теста. Вместо этого используйте синхронизацию потоков.

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

0
ответ дан 24 November 2019 в 17:46
поделиться

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

-1
ответ дан 24 November 2019 в 17:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: