1.NULL和std::string::npos
首先我们先来看看两个代码:
QString string = "test";
if(string.toStdString().find("t") == NULL)
{
std::cout << "null";
}
else
{
std::cout << "not null";
}
QString string = "test";
if(string.toStdString().find("t") == std::string::npos)
{
std::cout << "null";
}
else
{
std::cout << "not null";
}
这两段代码的运行结果相同吗?
NULL在我们的本意中,它应该代表的是不存在。同样的std::string::npos是一个size_type类型,它代表的是一个size_type类型可以表示的最大值,用来表示一个不存在的位置。所以既然都代表不存在,那么理论上这两段代码运行的结果应该是相同的,但是结果却出乎我们的意料:
很明显,第一段代码的结果不是我们想要的。但是为什么呢?NULL为什么会出现这个问题?我们可以按住Ctrl,点击NULL,进去查看NULL的定义:
#define NULL 0
C++把NULL定义为0,这就很好理解了,我们查询"test"中是否有"t",std::string的查找函数find()会返回字符所在字串中的位置,所以它会把"t"所在的位置0返回出来,而NULL是等于0的,所以会出现程序判断错误的情况。
2.NULL和nullptr
在1中我们可以看到NULL的缺点,它被定义为0,所以是有缺陷的。为了弥补这个缺陷,C++ 11推出了新的表示空的关键字nullptr,它的类型是std:nullptr_t,能转换成任意指针类型,所以在需要表示空指针的地方,就可以用nullptr来表示。
注意一个坑,在初学的时候容易犯的错,初始化string的时候,让它等于nullptr或者NULL…,这些都是不行的!!!
有人会觉得既然NULL和nullptr代表空,那么直接让string的值为空就可以,但是这样是错误的(虽然在编译阶段不会报错,但是运行时会出现崩溃的情况,因为string的构造函数是不接受nullptr或者0值的):
QString string = nullptr;
std::string test = nullptr;
QString string = NULL;
std::string test = NULL;
但是我们可以让一个指向string的指针指向空:
QString *string = nullptr;
std::string *test = nullptr;
这样就不会有问题了,因为这是指向string的指针,指针是可以指向空指针nullptr或者NULL的。