C++ Nullptr 并检查指针是否指向有效对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11279715/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Nullptr and checking if a pointer points to a valid object
提问by FatalCatharsis
In a couple of my older code projects when I had never heard of smart pointers, whenever I needed to check whether the pointer still pointed to a valid object, I would always do something like this...
在我从未听说过智能指针的几个较旧的代码项目中,每当我需要检查指针是否仍然指向有效对象时,我总是会做这样的事情......
object * meh = new object;
if(meh)
meh->member;
Or when I needed to delete the object safely, something like this
或者当我需要安全删除对象时,像这样
if(meh)
{
delete meh;
meh = 0;
}
Well, now I have learned about the problems that can arise from using objects and pointers in boolean expressions both with literal numbers, the hard way :. And now I've also learned of the not so new but pretty cool feature of C++, the nullptr
keyword. But now I'm curious.
好吧,现在我已经了解了在布尔表达式中使用对象和指针可能会出现的问题,这两种方法都带有文字数字,很难:。现在我还了解了 C++ 的一个不那么新但很酷的特性,nullptr
关键字。但现在我很好奇。
I've already gone through and revised most of my code so that, for example, when deleting objects I now write
我已经完成并修改了我的大部分代码,例如,在删除我现在编写的对象时
if(meh)
{
delete meh;
meh = nullptr;
}
Now I'm wondering about the boolean. When you pass just say an int into an if statement like this,
现在我想知道布尔值。当你将一个 int 传递给像这样的 if 语句时,
int meh;
if(meh)
Then it implicitly checks for zero without you needing to write it.
然后它会隐式地检查零,而无需您编写它。
if(meh == 0) // does the exact same check
Now, will C++ do the same for pointers? If pass in a char * like this to an if statement?
现在,C++ 会对指针做同样的事情吗?如果将像这样的 char * 传递给 if 语句?
char * meh;
if(meh)
Then will it implicitly compare it with nullptr? Because of how long I have been writing these ifs like this, it is second nature at this point to check if the pointers valid before using by typing if (object *) and then calling its members. If this is not the functionality why not? Too difficult to implement? Would solve some problems by removing yet another tiny way you could mess up your code.
那么它会隐式地将它与 nullptr 进行比较吗?由于我像这样编写这些 if 已经有多久了,此时通过键入 if (object *) 然后调用其成员来检查指针是否有效是第二天性。如果这不是功能,为什么不呢?实施太难?将通过删除另一种可能弄乱代码的小方法来解决一些问题。
回答by dcow
In C, anything that's not 0 is true. So, you certainly can use:
在 C 中,任何不为 0 的都是真的。所以,你当然可以使用:
if (ptrToObject)
ptrToObject->doSomething();
to safely dereference pointers.
安全地取消引用指针。
C++11 changes the game a bit, nullptr_t
is a type of which nullptr
is an instance; the representation of nullptr_t
is implementation specific. So a compiler may define nullptr_t
however it wants. It need only make sure it can enforce proper restriction on the casting of a nullptr_t
to different types--of which booleanis allowed--and make sure it can distinguish between a nullptr_t
and 0.
C++11 稍微改变了游戏,nullptr_t
是一个类型,其中nullptr
一个是实例;的表示nullptr_t
是特定于实现的。所以编译器可以随意定义nullptr_t
。它只需要确保它可以对将 a 强制转换nullptr_t
为不同类型(允许使用哪种布尔值)实施适当的限制,并确保它可以区分 anullptr_t
和 0。
So nullptr
will be properly and implicitly cast to the booleanfalse
so long as the compiler follows the C++11 language specification. And the above snippet still works.
只要编译器遵循 C++11 语言规范,Sonullptr
就会正确且隐式地转换为布尔值false
。上面的代码片段仍然有效。
If you delete a referenced object, nothing changes.
如果删除引用的对象,则不会发生任何变化。
delete ptrToObject;
assert(ptrToObject);
ptrToObject = nullptr;
assert(!ptrToObject);
Because of how long I have been writing these ifs like this, it is second nature at this point to check if the pointers valid before using by typing if (object *) and then calling it's members.
由于我像这样编写这些 if 已经有多久了,此时通过键入 if (object *) 然后调用它的成员来检查指针是否有效是第二天性。
No.Please maintain a proper graph of objects (preferably using unique/smart pointers). As pointed out, there's no way to determine if a pointer that is not nullptr
points to a valid object or not. The onus is on you to maintain the lifecycle anyway.. this is why the pointer wrappers exist in the first place.
不。请维护一个适当的对象图(最好使用唯一/智能指针)。正如所指出的,没有办法确定一个不是nullptr
指向有效对象的指针。无论如何,你有责任维护生命周期......这就是指针包装器首先存在的原因。
In fact, because the life-cycle of sharedand weakpointers are well defined, they have syntactic sugar that lets you use them the way you want to use bare pointers, where valid pointers have a value and all others are nullptr
:
事实上,因为共享指针和弱指针的生命周期是明确定义的,所以它们具有语法糖,让您可以像使用裸指针一样使用它们,其中有效指针具有值,其他所有指针是nullptr
:
Shared
共享
#include <iostream>
#include <memory>
void report(std::shared_ptr<int> ptr)
{
if (ptr) {
std::cout << "*ptr=" << *ptr << "\n";
} else {
std::cout << "ptr is not a valid pointer.\n";
}
}
int main()
{
std::shared_ptr<int> ptr;
report(ptr);
ptr = std::make_shared<int>(7);
report(ptr);
}
Weak
虚弱的
#include <iostream>
#include <memory>
void observe(std::weak_ptr<int> weak)
{
if (auto observe = weak.lock()) {
std::cout << "\tobserve() able to lock weak_ptr<>, value=" << *observe << "\n";
} else {
std::cout << "\tobserve() unable to lock weak_ptr<>\n";
}
}
int main()
{
std::weak_ptr<int> weak;
std::cout << "weak_ptr<> not yet initialized\n";
observe(weak);
{
auto shared = std::make_shared<int>(42);
weak = shared;
std::cout << "weak_ptr<> initialized with shared_ptr.\n";
observe(weak);
}
std::cout << "shared_ptr<> has been destructed due to scope exit.\n";
observe(weak);
}
Now, will C++ do the same for pointers? If pass in a char * like this to an if statement?
现在,C++ 会对指针做同样的事情吗?如果将像这样的 char * 传递给 if 语句?
So to answer the question: with barepointers, no. With wrappedpointers, yes.
所以要回答这个问题:用裸指针,没有。使用包装的指针,是的。
Wrap your pointers, folks.
把你的指针包裹起来,伙计们。
回答by M.M
It's not possible to test whether a pointer points to a valid object or not. If the pointer is not null but does not point to a valid object, then using the pointer causes undefined behaviour. To avoid this sort of error, the onus is on you to be careful with the lifetime of objects being pointed to; and the smart pointer classes help with this task.
无法测试指针是否指向有效对象。如果指针不为空但未指向有效对象,则使用该指针会导致未定义行为。为了避免这种错误,你有责任小心被指向的对象的生命周期;智能指针类有助于完成这项任务。
If meh
is a raw pointer then there is no difference whatsoever between if (meh)
and if (meh != 0)
and if (meh != nullptr)
. They all proceed iff the pointer is not null.
如果meh
是原始指针,则if (meh)
和if (meh != 0)
和之间没有任何区别if (meh != nullptr)
。如果指针不为空,它们都继续进行。
There is an implicit conversion from the literal 0
to nullptr
.
存在从文字0
到的隐式转换nullptr
。