《Effective Modern C++》读书笔记(5) -- 尽量使用nullptr而不使用0和NULL

前言

在之前看《C++ primer》一书,有关nullptr的解释已经很清楚了,这里有必要再整理一下。

0和NULL

C++11之前包括C,都会用到一个名为NULL的预处理器来给指针赋值,这个变量在头文件中cstdlib中定义,它的值就是0。我们都知道0是整形,不是指针。

// before C++11
#define NULL 0

// since C++11
#define NULL nullptr

在C++98,指针和整形的重载可能让你大吃一惊。例如:

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*)

当我们传递一个整数0的时候,由于0是一个整形,调用的是void f(int),但是当我们传递一个NULL,此时,在我们的印象中NULL使用来初始化指针的,所以应该调用void f(void*),这是错的。原因就是上面说的,NULL是一个宏定义变量。

这种违反直觉的行为是导致C++98程序员为避免指针和整型类型重载的问题,在C++11中,使用了nullptr

nullptr

nullptr有利之处在于它不是一个整形类型。而且,它也没有指针类型,但是你可以将它想象为一个符合所有类型的指针。

nullptr的类型

typedef decltype(nullptr) nullptr_t;

从上面可以看出,nullptr的类型是nullptr_t。而且类型std::nullptr_t隐式转换为所有原始指针类型,这就是使nullptr作为所有类型的指针的原因。

此时,调用:

f(nullptr);     // calls f(void*)

补充

c++ reference网页上发现,

// since C++11
#define NULL nullptr

是不是可以说明,我们同样可以使用NULL呢?

我写了这样一个代码

// 文件名test.cpp
void f(int);            // three overloads of f
void f(bool);
void f(void*);

f(nullptr);         // calls f(void*)
f(NULL);            // calls f(int)
f(0);           // calls f(int)

并如下编译(g++的版本为4.9.2)

g++ -std=c++14 test.cpp -o test

我们发现f(NULL)并不是我们想象中的那样,其中的原因是因为使用的标准库不一样导致的。所以为了避免出现这种现象,还是乖乖的使用nullptr好。

If you’re an experienced C++ programmer and are anything like me, you initially approached C++11 thinking, “Yes, yes, I get it. It’s C++, only more so.” But as you learned more, you were surprised by the scope of the changes. auto declarations, range-based for loops, lambda expressions, and rvalue references change the face of C++, to say nothing of the new concurrency features. And then there are the idiomatic changes. 0 and typedefs are out, nullptr and alias declarations are in. Enums should now be scoped. Smart pointers are now preferable to built-in ones. Moving objects is normally better than copying them. There’s a lot to learn about C++11, not to mention C++14. More importantly, there’s a lot to learn about making effective use of the new capabilities. If you need basic information about “modernC++ features, resources abound, but if you’re looking for guidance on how to employ the features to create software that’s correct, efficient, maintainable, and portable, the search is more challenging. That’s where this book comes in. It’s devoted not to describing the features of C++11 and C++14, but instead to their effective application. The information in the book is broken into guidelines called Items. Want to understand the various forms of type deduction? Or know when (and when not) to use auto declarations? Are you interested in why const member functions should be thread safe, how to implement the Pimpl Idiom using std::unique_ptr, why you should avoid default capture modes in lambda expressions, or the differences between std::atomic and volatile? The answers are all here. Furthermore, they’re platform-independent, Standards-conformant answers. This is a book about portable C++.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值