C++11

C++ 1 1 新特性总结

1.1、 nullptr:取代 NULL 专用于空指针

1.2、1.2、constexpr:

近似const, 可以修饰变量,也可以修饰函数,既可以赋值字面常量也可以赋值以const变量
重点:constexpr修饰的函数,生效于编译时而不是运行时, 重点应用于修饰函数使其在编译期大幅度被解释被constexpr修饰的函数,
无论是普通函数,还是类成员函数,必须是编译器可计算得到结果,即字面常量,不可是运行时才能获取的内容。

1.3、using取代typedef

typedef double db; //c99
using db = double; //c++11
typedef void(*function)(int, int);//c99,函数指针类型定义
using function = void(*)(int, int);//c++11,函数指针类型定义
template<class T> using twins = std::pair<T, T>; //更广泛的还可以用于模板

1.4、auto & decltype:

auto让编译器通过初始值来推算变量的类型。
decltype(变量)可以获取变量的类型
auto a = 10;
decltype(a) b = 2;

注意:decltype((a))的结果是引用,此时创建新的变量就将会报错

1.5、字符串和数值类型的转换

以前的atoi、itoa等等成为历史;
to_string:itoa成为历史;
stoi、stol、stoul、stoll、stoull、stof、stod、stold:atoX成为历史;

1.6、std::ref和std::cref

分别对应变量的引用和const引用,主要用于作为c++11函数式编程时传递的参数

1.7、std::chrono时间相关

1.8、原子变量

std::atomic<XXX>
用于多线程资源互斥操作,属c++11重大提升,多线程原子操作简单了许多
事实上基于c++11实现的无锁队列,让boost::lockfree无锁队列也将成为历史

1.9、正则表达式std::regex

恶心的C正则(regex.h)和boost正则成为历史

1.10、编译期断言static_assert

static_assert是用于涉及模板的assert,编译期就能发现不满足的情况,无需等到运行时出现core

1.11、 范围 for 语句
string str("hello world");
for (auto c : str) {
cout << c;
}


// 容器
2.1、tuple(元组) & 花括号初始化

using res_tp = std::tuple<bool, char, int, float, double>;
res_tp res(true, 'b', 11, 1.1, 100.1);

2.2、hash正式进入stl

unordered_map、unordered_set、unordered_multimap、unordered_multiset。extstl扩展方式的使用hash成为历史。

2.3、emplace:

作用于容器,区别于push、insert等,如push_back是在容器尾部追加一个容器类型对象,emplace_back是构造1个新对象并追加在容器尾部
对于标准类型没有变化,如std:;vector<int>,push_back和emplace_back效果一样。
改进点:避免无用临时变量。

2.4、shrink_to_fit
减少日常程序无意义的内存空间占用;
push、insert这类操作会触发容器的capacity,即预留内存的扩大,实际开发时往往这些扩大的区域并没有用途;
std::vector<int> v{1, 2, 3, 4, 5};
v.push_back(1);
std::cout << "before shrink_to_fit: " << v.capacity() << std::endl;
v.shrink_to_fit();

// 类
3.1、构造函数

3.1.1、控制构造函数

1、default关键字生成默认构造函数和析构函数
default的默认构造方式可生成:默认无参数的构造函数、拷贝构造函数、赋值构造函数,析构函数同样可以由default默认构造
class A11 {
int data;
public:
A11() = default;
~A11() = default;
A11 (int _data):data(_data) {}
};

3.1.2、delete关键字禁止拷贝构造、禁止赋值构造、禁止自定义参数的构造函数
**注意析构函数不可由delete修饰
c++11以前的方式,是把需要禁止的构造函数,放在private里使外部无法调用;
class noncopyable {
protected:
constexpr noncopyable() = default;
~noncopyable() = default;
noncopyable(const noncopyable &) = delete;
noncopyable &operator= (const noncopyable &) = delete;
};

3.1.3、右值引用std::move()
std::string a = "123"; //或std::string &&a = "123";显示的标识a是全局字符串"123"的右值引用
LOG(INFO) << "at first, std::string a is: " << a; //打印123
/*右值"123", 它的所有者将从原先的左值(变量std::string a), 转移到新的左值(std::vector v)
*所以, 使用std::move时一定保证, 以前的左值不再真需要了. 典型使用场合就是: (构造)函数的参数, 避免了再复制*/
v.push_back(std::move(a));

3.2、override和final
作用于虚函数,更多的作用是:显式的标识是否应该多态继承或不应该
3.2.1、override:子类用override修饰其虚函数,表示要多态继承基类的虚函数。不可以修饰非虚函数
3.2.2、final:基类用final修饰其虚函数,意外其子类不可以多态继承该虚函数

4、lambda、bind、function:函数式编程是c++11重要亮点之一

4.1、直接lambda表达式
int a = 1, b = 2;
auto multi = [](int a, int b){
b = a + a + a;
return a + b;
};

4.2、c++11风格的函数指针std::function & std::bind

5、动态指针

这也是c++11一个重要亮点

如同函数式编程,动态指针同样大量移植了原先boost里的东西

5.1、unique_ptr

功能基本对应boost的scoped_ptr,或之前stl的auto_ptr,生命周期随构造者,reset自动析构再重新构造,get判断是否有效、支持放在容器内;真正意义智能指针。
不论是临时变量指针、类成员指针变量.....90%的指针都应该用这个。

5.2、shared_ptr

功能对于boost的shared_ptr,可以有多个持有者的共享指针,即所谓引用计数型指针,直到最后一个持有者delete释放时,其指向的资源才会真正被释放
典型应用案例:如对同一个全局无锁队列对象由shared_ptr封装,多线程的多个持有者均持有对其的引用。直到全部线程都释放掉对其的引用时,该无锁队列对象才会被最终销毁。
也就是shared_ptr适合用于管理“全局动态资源”。

6、多线程与互斥同步(互斥锁,条件变量)这也是c++11的一个重要亮点

 

posted @ 2018-10-22 11:01  j_shuang  阅读(162)  评论(0编辑  收藏  举报