C++中NULL和nullptr的区别、const和define区别、typename关键词的使用详解

**

null:

**

  • null的nullptr的区别:在c中null被定义为(void*) 0,所以null既可以表示空指针,也可以表示整数0,也就是可以隐式类型转换,因为c中没有重载的概念,所以不会发生什么大问题,但是在c++中,因为会发生重载,我们在传空指针的时候,很容易被编译器认为是0,调用的函数就会发生错误,还有其它种种问题,所以c++为了解决这种二义性的问题,所以直接将null定义为整数0,不代表其它意思,然后用nullptr来代表空指针,它是不会发生隐式类型转换的,因为它在系统中是以类的形式定义的,然后做了一些操作,让它不会发生隐式类型转换和其它错误,nullptr就代表空指针不代表其它,而且这个空指针是安全的
  • 这个是NULL的定义:
       #ifndef NULL
       #ifdef __cplusplus
       #define NULL 0
       #else
       #define NULL ((void *)0)
       #endif
       #endif

void test(int)
{
cout<<"tset(int)"<<endl;
}
void test(int*)
{
cout<<"test(int*)"<<endl;
}
int main()
{
tset(0);
test(NULL);
test((int*)NULL);
return 0;
}

C++中NULL和nullptr的区别、const和define区别、typename关键词的使用详解_第1张图片

  • 程序本意是想通过test(NULL)调用指针版本的f(int*)函数,但是由于NULL被定义成0,因此与程序的初衷相悖,只有第3个调用int*的函数成功
  • 为了考虑兼容性,C++11并没有消除常量0的二义性,C++11给出了全新的nullptr表示空值指针,C++11为什么不在NULL的基础上进行扩展,这是因为NULL以前就是一个宏,而且不同的编译器厂商对于NULL的实现可能不太相同,而且直接扩展NULL,可能会影响以前旧的程序,因此为了避免混淆,C++11提供了nullptr,
    nullptr代表一个指针空值常量,并且nullptr是有类型的,其类型为nullptr_t,仅仅可以被隐式转化为指针类
    型,nullptr_t被定义在头文件中:
typedef  (nullptr) nullptr_t;
  • 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的,在C++11中,sizeof(nullptr) 与sizeof((void*)0)所占的字节数是相同,为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr

**

const和define的区别:

**

  • define是在预处理阶段就执行的,并且define仅仅是简单的宏替换没有类型,只是照原样替换进去不做任何处理,而const是在程序编译时执行的,而且const是具有类型,程序会进行类型检查,也就是说其实define定义并不是什么常量,而是一种替换,因为是替换我们在替换常量时才会觉得他定义的是常量,它本身是不具有类型的,而const是具有常量属性的它定义出来的东西就是常量,只不过有时我们可以进行强制类型转换,所以它的常属性就不那么明显了,相比之下define好像更好用,不过这种好用只是在简单的宏替换的情况下,如果定义的宏比较复杂,那会发生各种意想不到的操作,相关例子网上有很多,所以定义常量是推荐用const

    在这里插入图片描述C++中NULL和nullptr的区别、const和define区别、typename关键词的使用详解_第2张图片
    **

typename:

**

  • 使用typename的原因是你定义了一个模板类或函数,但是你定义好之后要使用它中的东西,但是你不想给模板传叁(因为你可能正在写另一个模板函数或类,参数需要别人传,但你又想嵌套使用你写的一个模板),这样做的话,因为编译器看见你使用的模板函数或类,但没有传参(也不是完全没有传参,只不过传的还是模板参数),它就以为你可能错了,会报错,因为使用模板必需得传参,所以我们提出了typename这种解决方法,就是在你要这样使用模板函数或类时,在最前面加上关键词typename,告诉编译器你现在不想传参,因为你在写另一个模板,这样编译器在编译的时候就会绕过它,不会报错
  • 例如下面这几个类中,second就会出错,虽然没有进行提示,但编译时会有错误:
 template <class T>
class first
{
public:

	void test()
	{
		cout << "test";
	}

	
};

template <class T>
class first2
{
	typedef first<T> f;
};

template <class T>
class second
{
public:
	typedef first2<T>::f f;


};

你可能感兴趣的:(C++中NULL和nullptr的区别、const和define区别、typename关键词的使用详解)