C++11(一)新的标准

一、统一的列表初始化

1.1 { }花括号初始化

C++98中提供的初始化:

struct Point
{
	int _x;
	int _y;
};
int main()
{
	int array1[] = { 1, 2, 3, 4, 5 };
	int array2[5] = { 0 };
	Point p = { 1, 2 };
	return 0;
}

C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可添加等号(=),也可不添加。

struct Point
{
	int _x;
	int _y;
	Point(int x, int y) 
		:_x(x)
		,_y(y)
	{
		cout << "Point(int x, int y)" << endl;
	}
};
int main()
{
	// 等号= 可以省
	int x1 = 1;
	int x2{ 2 };

	int array1[]{ 1, 2, 3, 4, 5 };
	int array2[5]{ 0 };
	Point p{ 1, 2 };

	// C++11中列表初始化也可以适用于new表达式中
	int* pa = new int[4]{ 1,2,3,4 };
	Point* ptr = new Point[2]{ {2,2},{3,3} };
	return 0;
}

1.2 explicit关键字

防止隐式类型转换
我们之前学习类和对象时知道,单参的构造函数具有隐式类型转换的作用,但是我们有些时候,不想让他进行隐式类型转化。

// 单参数
class A
{
private:
	int _a;
public:
	explicit A(int a)
		:_a(a)
	{}
};
int main()
{
	A a1(1);
	A a2 = { 2 };// 这里就是 2转换成一个int对象,再拷贝构造给a2对象
	return 0;	
}

1.3 std::initializer_list

int main()
{
	// C++98
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);

	// C++11
	vector<int> v2 = { 1,2,3,4,5,6,7 };

	initializer_list<int> il = { 1,2,3,4,5,6,7 };

	return 0;
}

支持的原理:新增了一个构造函数(list,map,set等等都新增了这个构造函数,原理也是一样的)
在这里插入图片描述

initializer_list在C++里面是一个容器,把一个花括号及其里面的内容(看做一个整体)传给il对象,这个il对象的类型就是initializer_list

在这里插入图片描述
模拟实现:

vector(initializer_list<T> ilt)
{
	typename initializer_list<T>::iterator it = ilt.begin();
	while (it!=ilt.end())
	{
		ilt.push_back(*it);
		++it;
	}
}

二、声明

2.1 auto

在C++98中auto是一个存储类型的说明符,表明变量是局部自动存储类型,但是局部域中定义局部的变量默认就是自动存储类型,所以auto就没什么价值了。C++11中废弃auto原来的用法,将其用于实现自动类型推断。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初始化值的类型。

int main()
{
	int i = 10;
	auto p = &i;
	auto pf = strcpy;
	cout << typeid(p).name() << endl;
	cout << typeid(pf).name() << endl;

	map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
	//map<string, string>::iterator it = dict.begin();
	auto it = dict.begin();

	return 0;
}

2.2 decltype

关键字decltype将变量的类型声明为表达式指定的类型。

int main()
{
	const int x = 1;
	double y = 2.2;

	
	decltype(x) z = 1;	// 拿x的类型来定义新的变量
	decltype(x * y) ret;// ret的类型是double
	decltype(&x) p;		// p的类型是int*
	return 0;
}

实用场景:
在定义模板的时候特别有用,因为只有等到模板被实例化时才能确定类型

int func(int a)
{
	cout << "int func(int a)" << endl;
	return a;
}
int main()
{
	int(*pfunc1)(int) = func;  //函数指针
	auto pfunc2 = func;
	decltype(&func) pfunc3;
	
	// 只能用decltype的场景——模板
	vector<decltype(func)> v;
	//vector<auto> v;报错
	return 0;
}

2.3 nullptr

空指针是不会指向有效数据的指针。以前C++在源代码中使用0表示这种指针,但是内部表示可能不同。这带来了一些问题,因为这使得0既可以表示指针常量,又可以表示整型常量。所以出于清晰和安全的角度考虑,C++11中新增了nullptr,用于表示空指针。

#ifndef NULL
#ifdef __cplusplus
#define NULL   0
#else
#define NULL   ((void *)0)
#endif
#endif

三、STL中的一些变化

3.1 新增容器

这几个新增容器中,实际最有用的是unordered_mapunordered_set
在这里插入图片描述
vector与array的区别
array的价值:
1、支持迭代器,更好兼容STL
2、对于越界的检查

int a[10];
	a[14] = 0;		//抽查 *(a+14)=0;
	array[14] = 0;	//必查 array.operator[](14)=0;
					//调用assert,断言检查

3.2 新增一些好用高效的接口

比如:初始化列表、右值引用版本的接口函数、移动构造、移动赋值
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值