智能指针
- 使用new和malloc申请的内存空间,没有被释放会造成内存泄漏,为了一劳永逸,提出了智能指针,自动回收内存。
- 智能指针将一个计数器与对象相关联,引用计数器跟踪该类有多少个对象共享同一个指针,计数器初始化为1,当减少至0的时候就删除指针。
常用指针简介
- auto_ptr:不支持复制(拷贝构造)和赋值(=),但是赋值时却不会报错,有很多问题。
- unique_ptr:在赋值和复制时会报错。是在要赋值使用std::move
- share_ptr:基于引用计数的指针,可以随意的赋值。但是循环引用时会出问题,要么手动打开环,要么使用weak_ptr。
- weak_ptr:弱引用,不计数,但是不保证指向的内存一定有效,使用前需要判定是否为空。
- 选用:如果需要指向多个指向同一个对象的指针,应该选择share_ptr。如果程序不需要指向多个对象的指针,则可以使用unique_ptr。
Lambda表达式
[capture](parameters) mutable ->return-type{statement}
-
1.[capture]:捕捉列表。捕捉列表总是出现在Lambda函数的开始处。实际上,[]是Lambda引出符。编译器根据该引出符判断接下来的代码是否是Lambda函数。捕捉列表能够捕捉上下文中的变量以供Lambda函数使用;
-
2.(parameters):参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号“()”一起省略;
-
3.mutable:mutable修饰符。默认情况下,Lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空);
-
4.->return-type:返回类型。用追踪返回类型形式声明函数的返回类型。我们可以在不需要返回值的时候也可以连同符号”->”一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导;
-
5.{statement}:函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。
#include<iostream>
using namespace std;
int main()
{
int a = 1;
int b = 2;
auto func = [=, &b](int c)->int {return b += a + c;};
return 0;
}
例子
- 1.[=,&a,&b]表示以引用传递的方式捕捉变量a和b,以值传递方式捕捉其它所有变量;
- 2.[&,a,this]表示以值传递的方式捕捉变量a和this,引用传递方式捕捉其它所有变量。
nullptr
- 在某种意义上来说,传统 C++ 会把 NULL、0 视为同一种东西,这取决于编译器如何定义 NULL,有些编译器会将 NULL 定义为 ((void*)0),有些则会直接将其定义为 0。
- 主要是为了替换NULL。
auto
- auto 在很早以前就已经进入了 C++,但是他始终作为一个存储类型的指示符存在。
- auto 不能用于函数传参。
decltype
-
decltype 关键字是为了解决 auto 关键字只能对变量进行类型推导的缺陷而出现的。它的用法和 sizeof 很相似:
decltype(表达式)
区间迭代
- C++11 引入了基于范围的迭代写法,我们拥有了能够写出像 Python 一样简洁的循环语句。
- 最常用的 std::vector 遍历将从原来的样子:
// & 启用了引用
for(auto &i : arr) {
std::cout << i << std::endl;
}
初始化列表
- C++11 提供了统一的语法来初始化任意的对象,例如:
struct A {
int a;
float b;
};
struct B {
B(int _a, float _b): a(_a), b(_b) {}
private:
int a;
float b;
};
无序容器
-
C++11 引入了两组无序容器:
std::unordered_map/std::unordered_multimap
std::unordered_set/std::unordered_multiset。 -
无序容器中的元素是不进行排序的,内部通过 Hash 表实现,插入和搜索元素的平均复杂度为 O(constant)。
正则表达式
- C++11 提供的正则表达式库操作 std::string 对象,对模式 std::regex (本质是 std::basic_regex)进行初始化,通过 std::regex_match 进行匹配,从而产生 std::smatch (本质是 std::match_results 对象)。
模板增强
- 传统 C++ 中,模板只有在使用时才会被编译器实例化。只要在每个编译单元(文件)中编译的代码中遇到了被完整定义的模板,都会实例化。这就产生了重复实例化而导致的编译时间的增加。并且,我们没有办法通知编译器不要触发模板实例化。