【C++11】nullptr关键字

转载于:http://blog.csdn.net/soaliap/article/details/7663865

从1972年C语言刚刚诞生以来,常数0就扮演着整数(int)0和空指针( null pointer )两种角色。为了避免理解上的二义性,C语言通常使用NULL宏来表示空指针,NULL宏通常被定义为(void *)0或0, 而C++仅仅采用0来表示空指针,这样存在一个问题:比如对于重载函数 fun(char *) 和 fun(int) 的调用来说,若直接用NULL作为参数调用fun(NULL),我们可能认为NULL作为空指针的表示,应该调用 fun(char *) 函数,然而NULL实际上的值为0,就会调用  fun(int) 。 nullptr 关键字正是为了解决这一问题而产生的。

nullptr 能够转换成任何指针类型(包括成员函数指针和成员变量指针)和bool类型(这是为了兼容普通指针都能使用 if(ptr) 判断是否为空指针的形式),但是不能被转换为整数0。

下面分析并测试了libcxx中 nullptr_t 的实现,对于转换为bool型别的调用还有些困惑。

// test.cpp
#include <iostream>
using std::cout;
using std::endl;

namespace myname {

struct nullptr_t
{
    void * _;

    struct __nat {int __for_bool_;};

    nullptr_t(int __nat::*) {} // 构造函数,参数可以是0(空指针),或者&__nat::__for_bool_

    operator int __nat::*() const {return 0;} // 不理解为什么转换为bool型时会调用此转换函数
	// operator bool() const {return 0; /* or return false; */} // 为什么不这样实现?

    template <class _Tp> 
	operator _Tp* () const {return 0;} // 转换为非成员变量指针、非成员函数指针的普通指针
	
    template <class _Tp, class _Up> 
	operator _Tp _Up::* () const {return 0;} // 转换为成员变量指针或成员函数指针

    friend bool operator==(nullptr_t, nullptr_t) {return true;}
    friend bool operator!=(nullptr_t, nullptr_t) {return false;}
    friend bool operator<(nullptr_t, nullptr_t) {return false;}
    friend bool operator<=(nullptr_t, nullptr_t) {return true;}
    friend bool operator>(nullptr_t, nullptr_t) {return false;}
    friend bool operator>=(nullptr_t, nullptr_t) {return true;}
};

struct Test {};

}

using namespace myname;

inline nullptr_t __get_nullptr_t() {return nullptr_t(0);}
#define nullptr __get_nullptr_t()

int main(int argc, char *argv[])
{
	char *pch = nullptr;	// ok, __get_nullptr_t() => nullptr_t::nullptr_t(0) => template <class _Tp> nullptr_t::operator _Tp* () const
	int *pint = nullptr;	// ok, __get_nullptr_t() => nullptr_t::nullptr_t(0) => template <class _Tp> nullptr_t::operator _Tp* () const
	bool    b = nullptr;	// ok, __get_nullptr_t() => nullptr_t::nullptr_t(0) => nullptr_t::operator int __nat::*() const
	//int     n = nullptr;	// error: cannot convert 'myname::nullptr_t' to 'int' in initialization
	int Test::*p = nullptr;	// ok, __get_nullptr_t() => nullptr_t::nullptr_t(0) => template <class _Tp, class _Up> operator _Tp _Up::* () const
	void (Test::*pfn)(int, char) = nullptr;	// ok, __get_nullptr_t() => nullptr_t::nullptr_t(0) => template <class _Tp, class _Up> operator _Tp _Up::* () const
	return 0;
}

 参考: 维基百科 C++11 ( http://en.wikipedia.org/wiki/C%2B%2B11 )

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt 场景、视图、项应用实例,Qt整套源码,喜欢请下载: Link: #include <QGraphicsLineItem> class Node; class Link : public QGraphicsLineItem { public: Link(Node *formN, Node *toN); ~Link(); inline Node *formNode()const { return myFormNode; } inline Node *toNode() const { return myToNode; } void setColor(const QColor &c); QColor color()const; void trackNodes(); private: Node *myFormNode; Node *myToNode; }; Node: #ifndef NODE_H #define NODE_H #include <QGraphicsItem> #include <QSet> class Link; class Node : public QGraphicsItem { public: Node(); ~Node(); inline void setText(const QString &text;); inline QString text()const {return myText;} inline void setTextColor(const QColor &c) { myTextColor = c; update();} inline QColor textColor()const{return myTextColor;} inline void setBackgroundColor(const QColor &c) { myBackgroundColor = c; update();} inline QColor backgroundColor()const{return myBackgroundColor;} inline void setOutLineColor(const QColor &c) { myOutLineColor = c; update();} inline QColor outLineColor()const{return myOutLineColor;} void addLink(Link *l); void removeLink(Link *l); QRectF boundingRect()const Q_DECL_OVERRIDE; QPainterPath shape() const Q_DECL_OVERRIDE; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE; protected: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; QVariant itemChange(GraphicsItemChange change, const QVariant &value;) Q_DECL_OVERRIDE; private: QRectF outlineRect()const; int roundness(double size)const;//计算圆角 QSet<Link *> myLinks; QString myText; QColor myTextColor; QColor myBackgroundColor; QColor myOutLineColor; }; #endif // NODE_H View: #ifndef GRAPHICSVIEW_H #define GRAPHICSVIEW_H #include <QWidget> #include <QGraphicsView> #include <QGraphicsScene> class GraphicsView : public QGraphicsView { Q_OBJECT public: explicit GraphicsView(QGraphicsScene *scene, QWidget *parent = 0); protected: void wheelEvent(QWheelEvent *e); }; #endif // GRAPHICSVIEW_H

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值