ToB企服应用市场:ToB评测及商务社交产业平台

标题: C++11特性总汇 [打印本页]

作者: 南七星之家    时间: 2024-7-26 13:27
标题: C++11特性总汇
利用方法
将鼠标移至 "C++11特性总汇" 上面, 右方出现导航小图标, 点击后在导航列表右上角点击固定, 再拖至左方空闲区域
该总汇编号与书中划一, 如有不明确的地方请检察原著

预定义宏

支持long long int类型

22.long long int n至少有64位
差别类型运算拓宽

23.(int)a + (long long int)b a会被提升为long long型后再举行运算
__cplusplus宏

24.用于C/C++混合编写, __cplusplus = 201103L可用作检测编译器所支持的C++版本
  1. #ifdef __cplusplus
  2. extern "C" {
  3. #endif
  4. //some code
  5. #ifdef __cplusplus
  6. }
  7. #endif
复制代码
assert断言

noexcept关键词

  1. void func() noexcept(true);
复制代码
如有非常,选择不抛出,而是直接终止运行并报错,括号内常量表达式true=不抛出, false=抛出
花括号初始化非静态成员

  1. private:
  2.      string name{"ABC"};
复制代码
允许对非静态成员利用sizeof

  1. private:
  2.      int n;      //sizeof(class::n)可编译通过
复制代码
友元模板

29.可在模板利用友元friend T;
final/override关键词

  1. private:
  2.      void func() final;        //派生不可重载
  3.      void oldFunc() override;  //重载必须同名,同参数,同常量性,且被重载的是虚函数
复制代码
默认模版类型

  1. template<typename T1, typename T2 = int> class C1;  //通过
  2. template<typename T1 = int, typename T2> class C2;  //报错,类模版默认类型需要从右往左
  3. template<typename T1 = int, typename T2> void func(T1 a, T2 b);  //通过,函数模版没有这规定
复制代码
外部模版

  1. extern template void func<int>(int);
复制代码
继续构造函数

  1. struct B: A{
  2.    using A::A;
  3. };
复制代码
委派构造函数

  1. class A{
  2. public:
  3.         A()                : A(1234){}     //先调用A(int)
  4.         A(int n1)   : A(n1, 'C'){}  //先调用A(int, char)
  5.         A(char c1)  : A(2, c1){}    //先调用A(int, char)
  6. private:
  7.         A(int n2, char c2)  : my_int(n2), my_char(c2){}
  8.         int my_int;
  9.         char my_char;
  10. }
复制代码
应用于模版:
  1. class A{
  2. public:
  3.         A(vector<int> &v)  : A(v.begin(), v.end());
  4.         A(deque<short> &d) : A(d.begin(), d.end());
  5. private:
  6.         template<class T> A(A n1, T n2)        : my_list(n1, n2) {}
  7.         list(int) my_list;
  8. }
复制代码
捕捉非常:
  1. class A{
  2. public:
  3.         A()
  4.         try : A(1234) {init();}
  5.         catch(...)    {error();}
  6.         A(int n)      {throw 0;}
  7.         //构造时执行error(), 而不执行init()
  8. }
复制代码
右值引用


  1. class A{
  2. public:
  3.         A()        : my_ptr(new int(1234)) {}
  4.         A(A &copy) : my_ptr(new int(*copy.my_ptr)) {}//新申请一块内存,避免重复析构同一块内存
  5.         ~A() {delete my_ptr;}
  6.         int *my_ptr;
  7. }
复制代码
  1. class A{
  2. public:
  3.         A()                      : my_ptr(new int(1234)) {}
  4.         A(const A& copy)  : my_ptr(*copy.my_ptr) {}
  5.         A(A&& move)       : my_ptr(move.my_ptr) {move.my_ptr = nullptr;}
  6.         ~A() {delete my_ptr;}
  7.         int* my_ptr;
  8. }
  9. A GetTmp() {
  10.         A tmp;
  11.         return tmp;
  12. }
  13. int main(){
  14.         A one = GetTmp();
  15. }
复制代码
1.执行GetTmp(),创建A1并初始化后返回,
2.创建并初始化A2,即A2(A1), 执行的是move而不是copy,它将A1的指针赋值给A2,并将A1的指针清掉,
3.析构A1,由于指针清掉了,所以初始化时的内存没有被开释
4.创建并初始化one,即one(A2),重复第2步,第3步
5.析构one,此时内存才真正被开释,它是A1初始化时申请的

引用折叠规则:
  1. typedef int T;
  2. typedef T& TR;      //or typedef T&& TR
  3. TR a;               //or TR& a , TR&& a
复制代码
TR定义为T&时,a的类型都是A&
TR定义为T&&时,TR/TR&&的类型为A&&,TR&的类型为A&
  1. template <typename T, typename U>
  2. void PF(T&& t, U& func){
  3.         func(std::forward<T>(t));
  4. }
复制代码
forward()与move()功能相同,完美转发可以或许把引用类型正确传给调用函数
explicit显式转换操作符

  1. class A{}
  2. class B{
  3. public:
  4.    explicit operator A() const {return A();}
  5. }
  6. void func(A a){}
  7. void main(){
  8.    B b;
  9.    A a1(b);                     //通过,直接初始化
  10.    A a2 = b;                    //错误
  11.    A a3 = static_cast<A>(b);    //通过,显式转换
  12.    func(b);                     //错误
  13. }
复制代码
列表初始化

  1. void func(initializer_list<int> numbers){}
  2. int main(){
  3.    func({1, 2, 3});
  4.    func({});
  5. }
复制代码
352.利用花括号初始化可以防止类型收窄
  1. const int x = 1234;
  2. char a = x;      //通过
  3. char b = {x};    //错误
  4. char* c = new char(1234);    //通过
  5. char* d = new char{1234};    //错误
复制代码
36.POD类型
37.团结体
38.用户自定义字面量
内联名字空间

  1. inline namespace space1{
  2. class A{};
  3. }
  4. namespace space2{
  5. A a;//A in space1
  6. class A{};
  7. A b;//A in space2;
  8. }
复制代码
模版的别名

  1. template<typename T> using NewName = std::map<T, char*>;
  2. NewName<int> a;      //等同于std::map<int, char*> a;
复制代码
SFINAE规则

  1. struct A{ typedef int my_int;
  2. };
  3. template <typename T>
  4. void func(typename T::my_int) {}      //#1
  5. template <typename T>
  6. void func(T) {}                  //#2
  7. int main(){
  8.    func<A>(1234);        //调用#1,因为存在    A::my_int
  9.    func<int>(1234);      //调用#2,因为不存在 int::my_int
  10. }
复制代码
>>右尖括号

41.两个右尖括号>在模板中不再被判断为右移, 需要右移需要加圆括号()
auto类型推导

  1. int a = 1;
  2. auto b = a;    //b的类型为int
复制代码
编译时推导
1): auto不能作函数形参类型
2): auto不能对布局体中的肥静态成员举行推导
3): auto不能声明数组
4): auto不能在实例化模板时作为模板参数
decltype类型推导
43.
  1. int a = 1;
  2. decltype(a) b;                         //b的类型为Int
  3. uding size_t = decltype(sizeof(0));    //与using/typydef合用
复制代码
编译时推导
1): decltype不能推导重载的函数
2): decltype将亡值推导为右值引用
3): decltype将左值推导为引用, 如 三元运算符, 带圆括号的左值, ++i, arr[0], *ptr
4): 以上都不是,则推导为本类型
追踪返回类型

  1. template<typename T1, typename T@>
  2. auto Func(const T1& a, const T@& b) -> decltype(a + b){
  3.    return a + b;
  4. }
复制代码
编译时推导
基于范围的for循环

  1. vector<int> MyVector= {1, 2, 3, 4};
  2. for(auto p : MyVector)
  3. {
  4.    cout << p << endl;    //p是解引用后的对象, 无需再*p解引用
  5. }
复制代码
智能指针

  1. enum class MyEnum: char{ e1, e2, e3};    //定义一个以char为底层实现的强类型枚举
  2. MyEnum a = e1;             //错误
  3. MyEnum b = MyEnum::e1;     //通过
  4. MyEnum c = 2;              //错误
  5. Myenum d = MyEnum::e2;
  6. if(d > 1){}                //错误
  7. if((char)d > 1){}          //通过
复制代码
unique_ptr只允许唯一指针指向内存
shared_ptr则允许共享同一块内存,它在实现上接纳了引用计数,只有在计数归零时才真正开释内存
weak_ptr不拥有控制权,其成员函数lock()返回其指向内存的一个shared_ptr对象,若其内存无效则返回nullptr
constexpr常量表达式

函数:
  1. unique_ptr<int> up1(new int(11));       //无法被复制
  2. unique_ptr<int> up2 = up1;              //编译错误, 指针唯一
  3. unique_ptr<int> up3 = move(up1);        //up1的控制权转移给up3
  4. up3.reset();                            //显式释放
  5. up1.reset();                            //不会出错
复制代码
1): 函数体只能有单一的return返回语句
2): 函数必须有返回值(不能为void)
3): 利用前必须已定义,即函数定义写在调用函数前面(放至后面则出错)
4): return返回语句表达式中必须是一个常量表达式,且不能是运行时函数
:
  1. constexpr int GetConst(){return 1;}
复制代码
它是编译时期的值,编译器可以选择不为它生成数据
自定义类: 必须对构造函数加上constexpr关键词
  1. constexpr int a = 1;
复制代码
1): 构造函数的函数体必须为空
2): 初始化列表只能由常量表达式来赋值
变长模板

  1. struct MyType{
  2.    constrxpr MyType(int x): my_int(x){}
  3.    int my_int;
  4. }
  5. constexpr MyType mt  = {2};
复制代码
typename之后带...来阐明这是一个参数包,该包名字为SomeType
构造类型B时,会调用B的私有基类构造函数,并举行参数包展开
即实际上执行的是A xy;
  1. template <typename T1, typename T2>
  2. class A{};
  3. template <typename... SomeType>
  4. class B: private A<SomeType...>{};
  5. B<int, char> xy;
复制代码
递归定义,在参数个数为0时结束,从右往左
参数包可以展开的位置:
1): 表达式
2): 初始化列表
3): 基类描述列表
4): 类成员初始化列表
5): 模板参数列表
6): 通用属性列表
7): lambda函数的捕捉列表
  1. template <typename... B>
  2. class MyClass;
  3. template <typename A, typename... B>
  4. class MyClass<A, B...>: private MyClass<B...>{
  5.    A my_a;
  6. };
  7. template<>
  8. class MyClass<>{};
复制代码
<blockquote>原子操作

[code]atomic_int  at1 {0};atomic at2 {0};int Set(){   at1 = 1;   at2 = 2;}int Show(){   cout




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4