И Java, и С#, и, возможно, многие другие языки тоже имеют предопределенный класс исключений, который вызывается, когда нулевой параметр используется там, где он не должен. Есть ли что-то подобное в С++? Если нет, существует ли еще одно предопределенное исключение, которое я могу использовать или я должен определить свой собственный?
Существует ли эквивалент С++ для исключения NullPointerException
Ответ 1
Выделение указателя NULL - это поведение undefined в С++, что означает, что код может работать. Исключение не гарантируется. Вы можете использовать
исключение (предоставить ему значимое значение - "p is NULL"
), но вам нужно будет выполнить проверку самостоятельно.
Ответ 2
Обычно, в С++ (или C в этом случае), никогда не разыскивает указатель NULL. Это имеет undefined поведение (вероятно, segfault для любой реализации, о которой я знаю, но что-то может произойти в соответствии со стандартом). Это, вероятно, плохо и на других языках, но я не знаю тех, кто достаточно, чтобы утверждать это.
Лучше всего предотвратить ситуацию, чем попытаться восстановить ее (что не может быть сделано на C или С++ в любом случае).
Обычный шаблон для предотвращения некоторых связанных ошибок программиста заключается в использовании assert()
внутри функциональных объектов, таких как:
int foo(int* myint)
{
// Ensure myint is not NULL
assert(myint);
// Do something with myint
(*myint)++;
return *myint;
}
Такие вызовы assert()
полностью игнорируются в выпусках и, следовательно, не требуют затрат на производство. Они просто помогают развитию. В отладочных сборках, и если условие не выполняется, программа прерывается немедленно с очень явным сообщением об ошибке. Запустив его через отладчик, вы можете легко проверить стек вызовов, чтобы провести расследование по этой причине.
Ответ 3
В С++ нет стандартного исключения для разыменования указателя NULL.
Если вы этого хотите, вы можете реализовать его самостоятельно. В UNIX настройте обработчик сигнала SIGSEGV и исключите из обработчика исключение. В Windows используйте API _set_se_translator() для установки обработчика "Структурированное исключение".
Ответ 4
FTR, в С# вы не используете NullReferenceException
для чего-либо, если вы не хотите, чтобы вас закололи ваши товарищи по команде. Вместо отклонения нулевых аргументов существует ArgumentNullException
. NREs должны быть выброшены во время выполнения, а не вы.
Но обратите внимание, что нет никакого фактического преимущества этого над утверждением, потому что вы не должны улавливать одно из них: если они выбрасываются, они указывают на ошибку. Это то, что Эрик Липперн вызывает исключенные из-за отсутствия исключений, и они являются вашей собственной ошибкой, и ваш код не должен делать с ними конкретно.
Ответ 5
Почти во всех случаях, связанных с неправильным использованием нулевого указателя (esp., deefencing it), стандарт С++ просто оставляет поведение undefined. Конкретный тип исключения не предусмотрен (и исключение не будет выбрано).
Одно из возможных исключений из этого правила приходит на ум. std::function
, который является стандартным библиотечным шаблоном С++ 11, который может использоваться для обертывания функций, может быть назначен нулевой указатель:
std::function<void(int)> func = nullptr;
И если вы затем попытаетесь вызвать функцию, завернутую им, выполнив func(arg);
для некоторого аргумента arg
, он выкинет исключение std::bad_function_call
.
Это, конечно, не полностью эквивалентно исключениям из нулевого указателя других языков, поскольку он гораздо менее применим.
Ответ 6
В С++ разыменование нулевой указатель приведет к поведению undefined, что в основном заканчивается приложением с ошибкой сегментации. В Visual Studio вы можете использовать расширения, такие как Structured Exception Handling (SEH), которые позволяют улавливать разыменование нулевого указателя.
Ответ 7
Вы можете заключить указатель в класс шаблона, который предоставляет ограниченный интерфейс для указателя. Он может выполнять проверку nullptr всякий раз, когда вы обращаетесь к указателю, и выдавать исключение.