C++ 检查空引用?
假设你有这样的东西:C++ 检查空引用?,c++,C++,假设你有这样的东西: int& refint; int* foo =0; refint = *foo; 如何验证引用是否为空以避免崩溃?这样的引用不能延迟初始化。它必须在声明时初始化 Visual C++中的 错误C2530:“refint”:引用 必须初始化 用你的代码 如果“修复”代码,崩溃(严格来说,未定义的行为)会在VC++v10中的引用使用时间发生 int* foo = 0; int& refint(*foo); int i(refint); // access v
int& refint;
int* foo =0;
refint = *foo;
如何验证引用是否为空以避免崩溃?这样的引用不能延迟初始化。它必须在声明时初始化 Visual C++中的
错误C2530:“refint”:引用 必须初始化
用你的代码 如果“修复”代码,崩溃(严格来说,未定义的行为)会在VC++v10中的引用使用时间发生int* foo = 0;
int& refint(*foo);
int i(refint); // access violation here
安全的方法是在引用初始化或赋值时检查指针
int* foo =0;
if (foo)
{
int& refint(*foo);
int i(refint);
}
尽管这仍然不能保证
foo
指向可用内存,也不能保证引用在作用域内时仍然指向可用内存。您没有,但当您有一个“null”引用时,您已经有了未定义的行为。在尝试通过取消引用指针来形成引用之前,应该始终检查指针是否为null
(您的代码是非法的;您不能创建未初始化的引用并尝试通过分配它来绑定它;您只能在初始化期间绑定它。)通常,您不能
无论是谁“创建空引用”(或者尝试创建空引用,我应该说)已经调用了未定义的行为,因此代码可能(或者可能不会)在您有机会检查任何内容之前崩溃
创建引用的人应该执行以下操作:
int *foo = 0;
if (foo) {
int &refint = *foo;
... use refint for something ...
}
通常情况下,如果调用方在
foo
为null时编写了*foo
,则认为调用方有问题,并且检查其他函数代码中的此类错误不是一个函数的责任。但是你可以乱扔东西,比如assert(&refint)代码>通过您的代码。它们可能有助于捕获调用者所犯的错误,因为毕竟对于您编写的任何函数,调用者很可能就是您自己。您不需要这样做,引用不能为null
阅读手册。要编译上述代码,必须切换顺序:
int* foo =0;
int& refint = *foo; // on actual PCs, this code will crash here
(可能有较旧的处理器或运行时架构在起作用。)…如果您确实想要一个空引用,请使用boost::optional
,就像一个符咒一样工作。以上所有答案都是正确的,但如果出于某种原因您想要这样做,我认为至少应该有一个人提供答案。我目前正试图在一些源代码中找到一个错误的引用,如果有人删除了这个引用并在某个时候将其设置为null,这将非常有用。希望这不会产生太多的反对票
#include <iostream>
int main()
{
int* foo = nullptr;
int& refint = *foo;
if(&refint == nullptr)
std::cout << "Null" << std::endl;
else
std::cout << "Value " << refint << std::endl;
}
#包括
int main()
{
int*foo=nullptr;
int&refint=*foo;
if(&refint==nullptr)
std::cout“崩溃将在reference init time发生”-promise?;-)崩溃不需要(而且通常不需要)在引用初始时间发生。使用UB,任何事情都可能发生,包括没有崩溃。@Charles,在调试器中检查并编辑了我的假设。只有在VC++中,当我使用引用时,它才会崩溃。UB所有方面…你把写这篇文章的开发人员拖进一个黑暗的房间,一把椅子和一盏灯亮着。然后你用香烟烧掉它们,直到注意:在这种情况下,输出为Null,因为int*foo;恰好是nullptr。因为它未初始化,所以可以是任何东西。我会将它初始化为nullptr。