我认为如果空指针在函数中传递,只需让它gp,我们就可以轻松找到根本原因。但我的队友说我们应该避免生产代码中的gp次数,如果应用程序通常崩溃,客户端可能会感到不安,尽管根本原因可能会被某些空指针保护所覆盖。
当您需要验证指针时,您将使用哪种方法为空?
HRESULT function(const int* pNumber)
{
{ POINTER CHECK for pNumber... }
...
}
方法1 - 忽略无效案例
if(pNumber)
{
int a = *pNumber;
}
方法2 - 断言指针,在调试模式下发出警告
assert(pNumber);
int a = *pNumber;
方法3 - 保留调试消息并返回错误代码
if(!pNumber)
{
OutputDebugString(L"Error Null pointer in function.\n");
return E_POINTER;
}
方法4 - 抛出logic_error异常 - 让调用者捕获
if(!pNumber)
{
throw std::logic_error("Null pointer of pNumber in function");
};
答案 0 :(得分:2)
如果取消引用nullptr
,则输入未定义行为的土地。这意味着,您的编译器没有义务执行anything sensible,因此应该避免这种情况。它也可能决定,因为它是非法的,它从未发生过,因此它会删除相应的代码(从而对其进行优化),并且您遇到逻辑错误而不会遇到一般性保护错误。
如果assert
完全无效,我个人更喜欢nullptr
- 案例,但在这种情况下,引用可能更为明智。我不认为有一般政策,因为它在很大程度上取决于周围的逻辑。
答案 1 :(得分:1)
例外是一种严重的违约行为,如果您有两个通过接口进行通信的模块,这是有道理的。对于cpp单元本地的静态函数而言,抛出它并不是那么多。考虑在结束时访问数组。它还假设另一方将抓住它。
其他人都不够好。
assert(pNumber);
就是弱者。可能有一种行为
特定于发布模式,你不会抓住它。而且它是
仅限于您在调试中测试的输入范围(远远不够
从所有)。OutputDebugString
弱于断言。你最终会让开发者放手
事情随着错误消息滑动,你将会习惯这么多
将停止阅读它们。所以如果我没有使用例外,我会使用
assert(pNumber);
if(pNumber)
{
}
else
{
//Log with a logger which has different logging level to the level you seem fit
}
答案 2 :(得分:0)
我priffer方法2
assert(pNumber);
int a = *pNumber;
因为,在调试模式下,您可以轻松识别断言发生故障的位置。即使在发布模式下,它也确保空值不会继续进入内部功能。用户不会看到任何异常行为,应用程序将正常工作。