《Effective Morden C++》Item 8: Prefer nullptr to 0 and NULL.

引子

这一条目就比较简单了,就是宣传用nullptr来指代空指针,而不是之前的0或者NULL

正文

在老式C++中,显然0int类型,而NULL也是一个整数类型(int或者long)。总的来说,这两个常用来表示空指针的符号并不是真正的指针类型。这样,当我们在进行函数重载时会发生麻烦,例如:

void f(int);        // three overloads of f
void f(bool);
void f(void*);

f(0);               // calls f(int), not f(void*)

f(NULL);            // might not compile, but typically calls f(int). Never calls f(void*)

所以在C++98中,一些准则教育程序员不要同时重载int和指针类型。但在C++11中,移除了这个限制,因为我们有一个新的关键字nullptr来代表空指针。

但是,准确的说,nullptr也不是空指针类型而是std::nullptr_t类型。这里有点循环定义的意思在里面,因为std::nullptr_t类型就是nullptr的类型。

此时我们再调用f(nullptr)时就准确地调用了f(void*)而不是其他重载函数。因为nullptr不会被转换为基本类型。

不过虽然0可以被看作空指针,但是并不是int类型会被隐式转换为空指针,例如:

void test(void*);
int data = 0;

test(0);        //Ok, but not recommanded
test(data);     //Error, could not convert from "int" to "void*"

了解了上面的机制,你就很容易看懂最后这个模板的例子:

using MuxGuard = std::lock_guard<std::mutex>;

template<typename FuncType,
         typename MuxType,
         typename PtrType>
decltype(auto) lockAndCall(FuncType func, 
                           MuxType& mutex, 
                           PtrType ptr
{
  MuxGuard g(mutex);
  return func(ptr);
}

int    f1(std::shared_ptr<Widget> spw);         // call these only when
double f2(std::unique_ptr<Widget> upw);         // the appropriate
bool   f3(Widget* pw);                          // mutex is loc

std::mutex f1m, f2m, f3m;                       // mutexes for f1, f2, and f3

auto result1 = lockAndCall(f1, f1m, 0);         // error!
auto result2 = lockAndCall(f2, f2m, NULL);      // error!
auto result3 = lockAndCall(f3, f3m, nullptr);   // fine

上面前两次调用都失败了,这是由于0NULL都被推导为整数类型,并进一步传递个内部的函数func(这里是f1f2)。而整数类型无法被转换为指针类型,故代码错误。

总结

综上,我们有:

1.用nullptr代替0NULL来指示空指针。
2.不要同时重载参数为整数类型和指针类型的函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值