C++11中的一些新特性

本文详细介绍了C++11引入的新特性,包括列表初始化、变量类型推导、运行时类型识别(RTTI)、范围for循环、final和override的使用,以及默认成员函数的控制。此外,还探讨了lambda表达式的语法和应用,展示了如何利用这些新特性提升代码的简洁性和效率。
摘要由CSDN通过智能技术生成

列表初始化

C++11扩大了初始化列表的使用范围,所有的内置类型和用户自定义类型都可以使用列表初始化,=号可添加可不添加。

如:

int main()
{
	int arr1[] = { 5,4,3,2,1 };
	int arr2[]{ 1,2,3,4,5 };
	int *arr3 = new int[5]{ 6,7,8,9,10 };
	vector<int> v1{ 10,9,8,7,6 };
	vector<int> v2 = { 1,4,7,2,5,8 };
	return 0;
}

容器支持花括号列表初始化,本质上是增加了一个接收花括号参数initializer_list的构造函数。
在这里插入图片描述

变量类型推导

使用auto推导实际变量的实际类型,可以使代码更加简洁,直观。需要注意使用auto之前,必须对auto声明的类型进行初始化,否则编译器就无法推导出auto的实际类型。

如:

int main()
{
	unordered_map<string, int> umap{ {"小王", 18}, {"小刘", 18} };
	unordered_map<string, int>::iterator it = umap.begin();
	auto ti = umap.begin();
	return 0;
}

运行时类型识别:RTTI(Run-Time Type Identification),程序允许完之后才知道结果的实际类型。
C++98中支持RTTI

  1. typeid只能查看类型,不能用其结果定义类型;
  2. dynamic_cast只能应用于函数虚函数的继承体系中。

C++11中,使用decltype,根据表达式的实际类型推演出定义变量时所用的类型

  1. 推演表达式类型作为变量的定义类型:
int main()
{
	int a = 1, b = 2;
	decltype(a + b) c;
	cout << typeid(c).name() << endl;
	return 0;
}

在这里插入图片描述
2. 推演函数返回值的类型:

template<class T, class K>
T add(T a, K b)
{
	return a + b;
}

int main()
{
	cout << typeid(decltype(add(1, 1.1))).name() << endl;
	return 0;
}

在这里插入图片描述
这里只会推演返回值类型,不会执行函数。

范围for循环

容器支持范围for循环,是因为编译器将范围替换成了迭代器,也就是迭代器支持范围for循环。

int main()
{
	vector<int> vv{ 1,2,3,4,5,6 };
	for (const auto& e : vv)//范围for循环遍历时,若没有对元素的更改,则建议加上const,且加上引用,为了避免一直调用拷贝构造函数
	{
		cout << e << "  ";
	}
	cout << endl;
	return 0;
}

final 和 override

final:修饰类时,表明该类不能被继承,修饰虚成员函数时,表明该虚成员函数在继承体系中,不能被重写。

override:在多态体系中,派生类需要重写虚函数,加上override会检查是否完成了重写。

默认成员函数的控制

显式缺省函数:在默认函数定义或者声明时加上 = default,从而显式的让编译器生成该函数的默认版本,用 = default修饰的函数称为显式缺省函数。

删除默认函数:若要限制某些默认函数的生成,C++98中,将函数设置为private,并且不给出定义,这样调用就会报错。C++11中,在函数声明加上 = delete,该语法让编译器不生产对应函数的默认版本,称 = delete修饰的函数为删除函数。

lambda表达式

lambda表达式书写格式:[capature-list] (parameters) mutable-> return-type{statement};

参数解释:
capature-list:捕捉列表,编译器根据[]来判断接下里的代码是否为lambda函数,捕捉列表能够捕捉上下文中变量提供给lambda函数使用

  1. 值传递方式捕捉变量:[var]
  2. 值传递方式捕捉父作用域中所有变量:[=]
  3. 引用传递捕捉变量:[&var]
  4. 引用传递方式捕捉父作用域中所有变量:[&]
  5. 值传递方式捕捉当前this指针:[this]
    注意:捕捉列表不允许有变量重复传递,否则就会导致编译错误。传值捕捉的对象不能被改变,若想修改加上mutable,但是修改的只是lambda表达式中的值,不会修改父作用域中对象的值。

parameters:参数列表,与普通函数的参数列表一致,若不传递参数,可取消()
mutable:默认情况下,lambda函数是一个const函数,mutable可修改常性,使用该修饰符时,参数列表不能省略(即使为空)
->returntype:返回值类型,追踪返回类型形式声明函数的返回值类型,没有返回值时可省略,返回值类型明确时,也可省略,由编译器自动推导。
statement:函数体,可以使用参数列表中的参数,也可使用捕捉列表中的参数。

最简单的lambda函数为:[]{}。省略参数列表、返回值类型

lambda表达式之间不能相互进行赋值。

lambda表达式原理:还是依靠仿函数来实现,定义一个lambda表达式,实际上编译器会生成一个lamber_uuid类,仿函数的operator()的参数和实现,就是替换编译器生成的lamber_uuid仿函数的对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值