На новой работе я получаю пометки в обзорах кода для такого кода:
PowerManager::PowerManager(IMsgSender* msgSender)
: msgSender_(msgSender) { }
void PowerManager::SignalShutdown()
{
msgSender_->sendMsg("shutdown()");
}
Мне сказали, что последний метод должен читать:
void PowerManager::SignalShutdown()
{
if (msgSender_) {
msgSender_->sendMsg("shutdown()");
}
}
то есть, я должен поставить NULL
охрану вокруг msgSender_
переменной, даже если он является частным членом данных. Мне трудно удержаться от использования ругательств, чтобы описать, что я чувствую по поводу этого кусочка «мудрости». Когда я спрашиваю объяснения, я получаю кучу ужасных историй о том, как какой-то младший программист, один год, запутался в том, как должен работать класс, и случайно удалил члена, которого он не должен был иметь (и установил его NULL
потом Видимо), и все сразу взорвалось на месте сразу после выпуска продукта, и мы «научились нелегко, поверьте нам», что лучше просто NULL
проверить все .
Для меня это похоже на программирование культа грузов , простое и понятное. Несколько благонамеренных коллег искренне пытаются помочь мне «получить это» и посмотреть, как это поможет мне написать более надежный код, но ... я не могу не чувствовать, что они - те, кто этого не понимают ,
Разумно ли для стандарта кодирования требовать, чтобы каждый отдельный указатель, разыменованный в функции, проверялся в NULL
первую очередь - даже на частные элементы данных? (Примечание: чтобы дать некоторый контекст, мы делаем устройство бытовой электроники, а не систему управления воздушным движением или какой-либо другой продукт «отказ-равный-людям-умирать».)
РЕДАКТИРОВАТЬ : В приведенном выше примере msgSender_
соавтор не является обязательным. Если это когда-либо NULL
, это указывает на ошибку. Единственная причина, по которой он передается в конструктор, заключается в том, что PowerManager
его можно протестировать с помощью имитирующего IMsgSender
подкласса.
РЕЗЮМЕ : Было несколько действительно хороших ответов на этот вопрос, спасибо всем. Я принял один из @aaronps главным образом из-за его краткости. Похоже, что существует общее мнение, что:
- Обязательная
NULL
охрана для каждого разыменованного указателя является излишним, но - Вы можете обойти всю дискуссию, используя вместо этого ссылку (если возможно) или
const
указатель, и assert
операторы являются более понятной альтернативойNULL
охранникам для проверки выполнения предварительных условий функции.
null
и ничего не делать - это всего лишь способ переместить ошибку вниз по ходу выполнения, что значительно усложняет поиск источника.