【C++11】 列表初始化 auto 范围for 新增关键字 新增容器

简介: 【C++11】 列表初始化 auto 范围for 新增关键字 新增容器

1 列表初始化

由c语言的规则我们知道:一般只有数组才会支持用{}初始化,但是C++11新语法规定我们不仅可以用{}初始化各种对象(内置类型和自定义类型),还可以不加上前面的=符号(一般不建议这样使用,可读性不好),比如下面的用法:

struct Point
{
 int _x;
 int _y;
};
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]{ 0 };
 return 0;
}

但是这样初始化的原理是什么呢?其实在C++11中又增加了一个新的类:initializer_list

【initializer_list的介绍文档】

initializer_list使用场景:

std::initializer_list一般是作为构造函数的参数,C++11对STL中的不少容器就增加std::initializer_list作为参数的构造函数,这样初始化容器对象就更方便了。也可以作为operator=的参数,这样就可以用大括号赋值像vector,list等容器我们可以直接用{}赋值。

2d117b59c3c346bbaa5f10d10f6d705a.png

比如下面这种用法:

int main()
{
 vector<int> v = { 1,2,3,4 };
 list<int> lt = { 1,2 };
 // 这里{"sort", "排序"}会先初始化构造一个pair对象
 map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
// 使用大括号对容器赋值
v = {10, 20, 30};
 return 0;

2 auto && 范围for

这个语法我们早在讲解C++入门的时候就已经讲解了,感兴趣的老哥可以点击下面链接:【C++入门基础】

3 新增关键字

3.1 decltype

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

一些使用的场景:

template<class T1, class T2>
void F(T1 t1, T2 t2)
{
decltype(t1 * t2) ret;
cout << typeid(ret).name() << endl;
}
int main()
{
const int x = 1;
double y = 2.2;
decltype(x * y) ret; // ret的类型是double
decltype(&x) p;      // p的类型是int*
cout << typeid(ret).name() << endl;
cout << typeid(p).name() << endl;
F(1, 'a');
return 0;
}

其实上面的这些场景用auto也可以很好的代替,但是下面的情况就不能够用auto代替了:

vector<decltype(x*y)>,由于vector中需要的是具体的类型,所以无法使用auto.

3.2 default

假设你要使用某个默认的函数,但是因为一些原因这个函数没有默认生成。比如:我们提供了自己写的默认构造,编译器就不会生成默认构造了。但是我们可以用default强制编译器生成。

class Person
{
public:
 Person(const char* name = "", int age = 0)
 :_name(name)
 , _age(age)
 {}
 Person(const Person& p)
 :_name(p._name)
 ,_age(p._age)
 {}
 Person() = default;
private:
 bit::string _name;
 int _age;
};

但是上面程序好像并没有实际价值,在学习了右值引用和移动语义后我们可以强制编译器生成默认的移动构造等等。

3.3 delete

如果想要限制某些默认函数的生成,在C++98中,我们应该怎么做?

将该函数设置成private,并且只声明补丁,这样只要其他人想要调用就会报错。

但是C++11提供了更加简易的方式:用delete关键字指定函数即可。

用法:

class Person
{
public:
 Person(const char* name = "", int age = 0)
 :_name(name)
 , _age(age)
 {}
 Person(const Person& p) = delete;
private:
 bit::string _name;
 int _age;
};
int main()
{
 Person s1;
 Person s2(s1);//报错
 return 0;
}

3.4 final与override

这两个关键字博主在继承与多态的文章详细介绍过,有兴趣的老哥可以移步:

【继承与多态】

4 总结

总的来说本次介绍的新语法还是挺简单的,都是一些基础的内容,C++11系列还有内容没有更新完,我们下次再见啦!! ❤️ ❤️❤️

目录
相关文章
|
28天前
|
存储 编译器 C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(一)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
28天前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
41 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
28天前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
45 5
|
28天前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
26 3
|
28天前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
43 3
|
28天前
|
C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(二)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
28天前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
44 2
|
28天前
|
编译器 C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(三)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
28天前
|
存储 安全 编译器
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(一)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值
|
2月前
|
安全 程序员 编译器
C++ 11新特性之auto和decltype
C++ 11新特性之auto和decltype
34 3