C++ NULL与nullptr的区别
在C里面,由于处处都要使用指针,所以导致NULL遍布各地。我们先来看C99是怎么定义NULL的:
NULL can be defined as any null pointer constant. Thus existing code can retain definitions of
NULL as 0 or 0L, but an implementation may also choose to define it as (void*)0. This latter
form of definition is convenient on architectures where sizeof(void*) does not equal the
size of any integer type. It has never been wise to use NULL in place of an arbitrary pointer as a
function argument, however, since pointers to different types need not be the same size. Thelibrary avoids this problem by providing special macros for the arguments to signal, the one
library function that might see a null function pointer.
A null pointer constant is an integer literal (2.13.2) with value zero or a prvalue of type std::nullptr_t.
A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type
and is distinguishable from every other value of object pointer or function pointer type. Such a conversion
is called a null pointer conversion. Two null pointer values of the same type shall compare equal. The
conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the
sequence of a pointer conversion followed by a qualification conversion (4.4). A null pointer constant of
integral type can be converted to a prvalue of type std::nullptr_t. [ Note: The resulting prvalue is not a
null pointer value. —end note ]
A prvalue of type “pointer to cv T,” where T is an object type, can be converted to a prvalue of type “pointer
to cv void”. The result of converting a non-null pointer value of a pointer to object type to a “pointer to
cv void” represents the address of the same byte in memory as the original pointer value. The null pointer
value is converted to the null pointer value of the destination type.
A prvalue of type “pointer to cv D”, where D is a class type, can be converted to a prvalue of type “pointer
to cv B”, where B is a base class (Clause 10) of D. If B is an inaccessible (Clause 11) or ambiguous (10.2)
base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion is a
pointer to the base class subobject of the derived class object. The null pointer value is converted to the
null pointer value of the destination type.
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
#include <iostream>
#include <algorithm>
#include <memory>
void fun(int)
{
std::cout << "fuck1" << std::endl;
}
void fun(void *)
{
std::cout << "fuck2" << std::endl;
}
int main(int argc, char *argv[])
{
fun(NULL);
system("pause");
return ;
}
int main(int argc, char *argv[])
{
fun(nullptr);
system("pause");
return ;
}
struct Fuck
{
Fuck(char *){ }
};
int main(int argc, char *argv[])
{
auto p = std::make_shared<Fuck>(NULL);
throwing();
system("pause");
return ;
}
template<class _Ty,
class... _Types> inline
shared_ptr<_Ty> make_shared(_Types&&... _Args)
{ // make a shared_ptr
_Ref_count_obj<_Ty> *_Rx =
new _Ref_count_obj<_Ty>(_STD forward<_Types>(_Args)...);
shared_ptr<_Ty> _Ret;
_Ret._Resetp0(_Rx->_Getptr(), _Rx);
return (_Ret);
}
// TEMPLATE CLASS _Ref_count_obj
template<class _Ty>
class _Ref_count_obj
: public _Ref_count_base
{ // handle reference counting for object in control block, no allocator
public:
template<class... _Types>
_Ref_count_obj(_Types&&... _Args)
: _Ref_count_base()
{ // construct from argument list
::new ((void *)&_Storage) _Ty(_STD forward<_Types>(_Args)...);
}
_Ty *_Getptr() const
{ // get pointer
return ((_Ty *)&_Storage);
}
private:
virtual void _Destroy() _NOEXCEPT
{ // destroy managed resource
_Getptr()->~_Ty();
}
virtual void _Delete_this() _NOEXCEPT
{ // destroy self
delete this;
}
typename aligned_union<, _Ty>::type _Storage;
};
auto p = std::make_shared<Fuck>(nullptr);
最新文章
- 图解GitHub基本操作
- XSS quiz练习题做题过程及感悟
- EasyUi 方法传递多个参数值得方法
- input file上传文件扩展名限制
- 推荐一款超强大的基于Angularjs的自动完成(Autocomplete)标签及标签组插件–ngTagsInput
- Sql server之路 (六)上传服务器图片
- 【BZOJ】1015: [JSOI2008]星球大战starwar(并查集)
- SecureCRT显示中文和语法高亮
- xcode 插件管理工具
- SQLSERVER利用FOR XML PATH实现分组拼接字符串
- cat/tac/more/less 命令详解
- socket 编程中。 服务端用到多线程
- Python 线程同步锁, 信号量
- Python3内置函数——reversed() = 翻转我的世界
- java中常用jar包
- NSString 和 NSData 转换
- 05-老马jQuery教程-动画
- NavigationViewController页面间通信及传值
- HtmlImageGenerator字体乱码问题解决、html2image放linux上乱码问题解决
- c#进阶之浅析委托和事件
热门文章
- 《深度学习-改善深层神经网络》-第二周-优化算法-Andrew Ng
- Kbengine
- 非常实用的Sublime插件集合 – sublime推荐必备插件
- EasyPOI 教程以及完整工具类的使用
- JavaScript进阶 - 第5章 小程序,大作用(函数)
- Jenkins+Maven+Jmeter接口自动化持续集成测试
- BZOJ 1433 &;&; Luogu P2055 [ZJOI2009]假期的宿舍 匈牙利算法
- 2019湘潭校赛 H(dp)
- 前端CSS(1)
- tomcat7 fail to start inside Ubuntu Docker container