C++11新特性(一)
C++11新特性
- C++11新特性(一)
- 语法改进
- 统一的初始化方法
- 成员变量默认初始化
- auto关键字 用于定义变量,编译器可以自动判断的类型(前提:定义一个变量时对其进行初始化)
- decltype 求表达式的类型
- 智能指针 shared_ptr
- 空指针 nullptr(原来NULL)
- 基于范围的for循环
- 右值引用和move语义 让程序员有意识减少进行深拷贝操作
- 标准库扩充
- ? 无序容器(哈希表) 用法和功能同map一模一样,区别在于哈希表的效率更高
- 正则表达式 可以认为正则表达式实质上是一个字符串,该字符串描述了一种特定模式的字符串
- Lambda表达式
C++11新特性(一)
语法改进
统一的初始化方法
用于任何类型对象的初始化,在 C++11 中,可以直接在变量名后面跟上初始化列表,来进行对象的初始化。
成员变量默认初始化
构建一个类的对象不需要用构造函数初始化成员变量。
auto关键字 用于定义变量,编译器可以自动判断的类型(前提:定义一个变量时对其进行初始化)
定义迭代器 i 的时候,类型书写比较冗长,容易出错。然而有了 auto 类型推导,我们大可不必这样,只写一个 auto 即可。
decltype 求表达式的类型
自动类型推导
//auto与decltype的区别 auto 要求变量必须初始化,而 decltype 不要求。
auto varname = value;
decltype(exp) varname = value;
智能指针 shared_ptr
多个 shared_ptr 智能指针可以共同使用同一块堆内存,而且其实现上采用的是引用计数机制,有一个放弃堆内存的使用权,不会影响其他指向同一堆的 shared_ptr指针
#include <iostream>
#include <memory>
using namespace std;
int main()
{
//构建 2 个智能指针
std::shared_ptr<int> p1(new int(10));
std::shared_ptr<int> p2(p1);
//输出 p2 指向的数据
cout << *p2 << endl;
p1.reset();//引用计数减 1,p1为空指针
if (p1) {
cout << "p1 不为空" << endl;
}
else {
cout << "p1 为空" << endl;
}
//以上操作,并不会影响 p2
cout << *p2 << endl;
//判断当前和 p2 同指向的智能指针有多少个
cout << p2.use_count() << endl;
return 0;
}
/* 程序运行结果:
10
p1 为空
10
1
*/
空指针 nullptr(原来NULL)
nullptr 是 nullptr_t 类型的右值常量,专用于初始化空类型指针。 称为指针空值类型,nullptr 可以被隐式转换成任意的指针类型
int * a1 = nullptr;
char * a2 = nullptr;
double * a3 = nullptr;
同类型的指针变量都可以使用 nullptr 来初始化,编译器分别将 nullptr 隐式转换成 int、char 以及 double* 指针类型。另外,通过将指针初始化为 nullptr,可以很好地解决 NULL 遗留的问题
```bash
```bash
```cpp
#include <iostream>
using namespace std;
void isnull(void *c){
cout << "void*c" << endl;
}
void isnull(int n){
cout << "int n" << endl;
}
int main() {
isnull(NULL);
isnull(nullptr);
return 0;
}
/* 程序运行结果:
int n
void*c
*/
基于范围的for循环
for(表达式 1; 表达式 2; 表达式 3){
}
//程序实例
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
int main() {
char arc[] = "www.123.com";
int i;
//for循环遍历普通数组
for (i = 0; i < strlen(arc); i++) {
cout << arc[i];
}
cout << endl;
vector<char>myvector(arc,arc+3);
vector<char>::iterator iter;
//for循环遍历 vector 容器
for (iter = myvector.begin(); iter != myvector.end(); ++iter) {
cout << *iter;
}
return 0;
}
/* 程序运行结果:
www.123.com
www
*/
右值引用和move语义 让程序员有意识减少进行深拷贝操作
常量左值引用既可以操作左值,也可以操作右值
int num = 10;
const int &b = num;
const int &c = 10;
C++11 标准新引入了另一种引用方式,称为右值引用,用 "&&" 表示
int num = 10;
//int && a = num; //右值引用不能初始化为左值
int && a = 10;
和常量左值引用不同的是,右值引用还可以对右值进行修改
int && a = 10;
a = 100;
cout << a << endl;
/* 程序运行结果:
100
*/
move( arg ) ,将某个左值强制转化为右值
标准库扩充
? 无序容器(哈希表) 用法和功能同map一模一样,区别在于哈希表的效率更高
无序容器 | 功能 |
---|---|
unordered_map | 存储键值对 <key, value> 类型的元素,其中各个键值对键的值不允许重复,且该容器中存储的键值对是无序的。 |
unordered_set | 不再以键值对的形式存储数据,而是直接存储数据元素本身(当然也可以理解为,该容器存储的全部都是键 key 和值 value 相等的键值对,正因为它们相等,因此只存储 value 即可)。另外,该容器存储的元素不能重复,且容器内部存储的元素也是无序的。 |
unordered_multiset | 和 unordered_set 唯一的区别在于,该容器允许存储值相同的元素。 |
正则表达式 可以认为正则表达式实质上是一个字符串,该字符串描述了一种特定模式的字符串
Lambda表达式
匿名函数,简单地理解就是没有名称的函数
[外部变量访问方式说明符] (参数) mutable noexcept/throw() -> 返回值类型
{
函数体;
};
仿函数