• C++ 11 新特性


    一.统一的初始化方法

     1 int arr[3]{1, 2, 3};
     2 vector<int> iv{1, 2, 3};
     3 map<int, string> mp{{1, "a"}, {2, "b"}};
     4 string str{"Hello World"};
     5 int * p = new int[20]{1,2,3};
     6 struct A {
     7     int i,j; A(int m,int n):i(m),j(n) { }
     8 };
     9 A func(int m,int n ) { return {m,n}; }
    10 int main() { A * pa = new A {3,7}; }

    二.成员变量默认初始值

     1 class B
     2 {
     3 public:
     4     int m = 1234;
     5     int n;
     6 };
     7 int main()
     8 {
     9     B b;
    10     cout << b.m << endl; //输出 1234
    11     return 0;
    12 }

    三.auto关键字
    用于定义变量,编译器可以自动判断变量的类型

     1 auto i = 100; // i 是 int
     2 auto p = new A(); // p 是 A *
     3 auto k = 34343LL; // k 是 long long
     4 map<string,int,greater<string> > mp;
     5 for( auto i = mp.begin(); i != mp.end(); ++i)
     6 cout << i->first << "," << i->second;
     7 //i的类型是: map<string,int,greater<string> >::iterator
     8 
     9 class A { };
    10 A operator + ( int n,const A & a)
    11 {
    12     return a;
    13 }
    14 template <class T1, class T2>
    15 auto add(T1 x, T2 y) -> decltype(x + y) {
    16     return x+y;
    17 }
    18 auto d = add(100,1.5); // d是double d=101.5
    19 auto k = add(100,A()); // d是A类型

    四.decltype 关键字
    求表达式的类型

    1 int i;
    2 double t;
    3 struct A { double x; };
    4 const A* a = new A();
    5 decltype(a) x1; // x1 is A *
    6 decltype(i) x2; // x2 is int
    7 decltype(a->x) x3; // x3 is double
    8 decltype((a->x)) x4 = t; // x4 is double&

    五.智能指针shared_ptr
    头文件: <memory>
    通过shared_ptr的构造函数,可以让shared_ptr对象托管一个new运算符返回的指针,写法如下:回的指针,写法如下:回的指针,写法如下:
         shared_ptr<T> ptr(new T); // T 可以是 int ,char, 类名等各种类型
    此后ptr就可以像 T* 类型的指针一样来使用,即 *ptr 就是用new动态分配的
    那个对象,而且不必操心释放内存的事。
    多个shared_ptr对象可以同时托管一个指针,系统会维护一个托管计数。当
    无shared_ptr托管该指针时, delete该指针。
    shared_ptr对象不能托管指向动态分配的数组的指针,否则程序运行会出错

     1 #include <memory>
     2 #include <iostream>
     3 using namespace std;
     4 struct A {
     5     int n;
     6     A(int v = 0):n(v){ }
     7     ~A() { cout << n << " destructor" << endl; }
     8 };
     9 int main()
    10 {
    11     shared_ptr<A> sp1(new A(2)); //sp1托管A(2)
    12     shared_ptr<A> sp2(sp1); //sp2也托管 A(2)
    13     cout << "1)" << sp1->n << "," << sp2->n << endl; //输出1)2,2
    14     shared_ptr<A> sp3;
    15     A * p = sp1.get(); //p 指向 A(2)
    16     cout << "2)" << p->n << endl;
    17     //输出结果:
    18     //    1)2,2
    19     //    2)2
    20     sp3 = sp1; //sp3也托管 A(2)
    21     cout << "3)" << (*sp3).n << endl; //输出 2
    22     sp1.reset(); //sp1放弃托管 A(2)
    23     if( !sp1 )
    24         cout << "4)sp1 is null" << endl; //会输出
    25     A * q = new A(3);
    26     sp1.reset(q); // sp1托管q
    27     cout << "5)" << sp1->n << endl; //输出 3
    28     shared_ptr<A> sp4(sp1); //sp4托管A(3)
    29     shared_ptr<A> sp5;
    30     //sp5.reset(q); 不妥,会导致程序出错
    31     sp1.reset(); //sp1放弃托管 A(3)
    32     cout << "before end main" <<endl;
    33     sp4.reset(); //sp1放弃托管 A(3)
    34     cout << "end main" << endl;
    35     return 0; //程序结束,会delete 掉A(2)
    36 }
    37 //输出结果:
    38 //1)2,2
    39 //2)2
    40 //3)2
    41 //4)sp1 is null
    42 //5)3
    43 //before end main
    44 //3 destructor
    45 //end main
    46 //2 destructor
     1 #include <iostream>
     2 #include <memory>
     3 using namespace std;
     4 struct A {
     5     ~A() { cout << "~A" << endl; }
     6 };
     7 int main()
     8 {
     9     A * p = new A;
    10     shared_ptr<A> ptr(p);
    11     shared_ptr<A> ptr2;
    12     ptr2.reset(p); //并不增加ptr中对p的托管计数
    13     cout << "end" << endl;
    14     return 0;
    15 }
    16 //输出结果:
    17 //end
    18 //~A
    19 //~A
    20 //之后程序崩溃,
    21 //因p被delete两次

    六.空指针nullptr

     1 #include <memory>
     2 #include <iostream>
     3 using namespace std;
     4 int main() {
     5     int* p1 = NULL;
     6     int* p2 = nullptr;
     7     shared_ptr<double> p3 = nullptr;
     8     if(p1 == p2)
     9         cout << "equal 1" <<endl;
    10     if( p3 == nullptr)
    11         cout << "equal 2" <<endl;
    12     if( p3 == p2) ; // error
    13     if( p3 == NULL)
    14         cout << "equal 4" <<endl;
    15     bool b = nullptr; // b = false
    16     int i = nullptr; //error,nullptr不能自动转换成整型
    17     return 0;
    18 }
    19 //去掉出错的语句后输出:
    20 //equal 1
    21 //equal 2
    22 //equal 4

    七.基于范围的for循环

     1 #include <iostream>
     2 #include <vector>
     3 using namespace std;
     4 struct A { int n; A(int i):n(i) { } };
     5 int main() {
     6     int ary[] = {1,2,3,4,5};
     7     for(int & e: ary)
     8         e*= 10;
     9     for(int e : ary)
    10         cout << e << ",";
    11     cout << endl;
    12     vector<A> st(ary,ary+5);
    13     for( auto & it: st)
    14         it.n *= 10;
    15     for( A it: st)
    16         cout << it.n << ",";
    17     return 0;
    18 }
    19 //输出:
    20 //10,20,30,40,50,
    21 //100,200,300,400,500,

    八.右值引用和move语义
    右值:一般来说,不能取地址的表达式,就是右值,能取地址的,就是左值
    class A { };
    A & r = A(); // error , A()是无名变量,是右值
    A && r = A(); //ok, r 是右值引用
    主要目的是提高程序运行的效率,减少需要进行深拷贝的对象进行深拷贝的次数。的次数。

     1 #include <iostream>
     2 #include <string>
     3 #include <cstring>
     4 using namespace std;
     5 class String
     6 {
     7 public:
     8     char * str;
     9     String():str(new char[1]) { str[0] = 0;}
    10     String(const char * s) {
    11         str = new char[strlen(s)+1];
    12         strcpy(str,s);
    13     }
    14     String(const String & s) {
    15         cout << "copy constructor called" << endl;
    16         str = new char[strlen(s.str)+1];
    17         strcpy(str,s.str);
    18     }
    19     
    20     String & operator=(const String & s) {
    21         cout << "copy operator= called" << endl;
    22         if( str != s.str) {
    23             delete [] str;
    24             str = new char[strlen(s.str)+1];
    25             strcpy(str,s.str);
    26         }
    27         return * this;
    28     }
    29     // move constructor
    30     String(String && s):str(s.str) {
    31         cout << "move constructor called"<<endl;
    32         s.str = new char[1];
    33         s.str[0] = 0;
    34     }
    35     
    36     // move assigment
    37     String & operator = (String &&s) {
    38         cout << "move operator= called"<<endl;
    39         if (str!= s.str) {
    40             str = s.str;
    41             s.str = new char[1];
    42             s.str[0] = 0;
    43         }
    44         return *this;
    45     }
    46     ~String() { delete [] str; }
    47 };
    48 template <class T>
    49 void MoveSwap(T& a, T& b) {
    50     T tmp(move(a)); // std::move(a)为右值,这里会调用move constructor
    51     a = move(b); // move(b)为右值,因此这里会调用move assigment
    52     b = move(tmp); // move(tmp)为右值,因此这里会调用move assigment
    53 }
    54 
    55 int main()
    56 {
    57     //String & r = String("this"); // error
    58     String s;
    59     s = String("this");
    60     cout << "****" << endl;
    61     cout << s.str << endl;
    62     String s1 = "hello",s2 = "world";
    63     MoveSwap(s1,s2);
    64     cout << s2.str << endl;
    65     return 0;
    66 }
    67 //输出:
    68 //move operator= called
    69 //****
    70 //this
    71 //move constructor called
    72 //move operator= called
    73 //move operator= called
    74 //hello


    九.无序容器(哈希表)

     1 #include <iostream>
     2 #include <string>
     3 #include <unordered_map>
     4 using namespace std;
     5 int main()
     6 {
     7     unordered_map<string,int> turingWinner; //图灵奖获奖名单
     8     turingWinner.insert(make_pair("Dijkstra",1972));
     9     turingWinner.insert(make_pair("Scott",1976));
    10     turingWinner.insert(make_pair("Wilkes",1967));
    11     turingWinner.insert(make_pair("Hamming",1968));
    12     turingWinner["Ritchie"] = 1983;
    13     string name;
    14     cin >> name; //输入姓名
    15     4
    16         unordered_map<string,int>::iterator p = turingWinner.find(name);
    17     //据姓名查获奖时间
    18     if( p != turingWinner.end())
    19         cout << p->second;
    20     else
    21         cout << "Not Found" << endl;
    22     return 0;
    23 }
    24 //哈希表插入和查询的时间复杂度几乎是常数

    十.正则表达式

     1 #include <iostream>
     2 #include <regex> //使用正则表达式须包含此文件
     3 using namespace std;
     4 int main()
     5 {
     6     regex reg("b.?p.*k");
     7     cout << regex_match("bopggk",reg) <<endl; //输出 1, 表示匹配成功
     8     cout << regex_match("boopgggk",reg) <<endl; //输出 0, 表示匹配失败
     9     cout << regex_match("b pk",reg) <<endl; //输出 1, 表示匹配成功
    10     regex reg2("\d{3}([a-zA-Z]+).(\d{2}|N/A)\s\1");
    11     string correct="123Hello N/A Hello";
    12     string incorrect="123Hello 12 hello";
    13     cout << regex_match(correct,reg2) <<endl; //输出 1, 表示匹配成功
    14     cout << regex_match(incorrect,reg2) << endl; //输出 0, 表示匹配失败
    15 }

    十一.Lambda表达式只使用一次的函数对象,能否不要专门为其编写一个类?
    只调用一次的简单函数,能否在调用时才写出其函数体?

    形式:
    [外部变量访问方式说明符](参数表) ->返回值类型
    {
    语句组
    }
    [=] 以传值的形式使用所有外部变量
    [] 不使用任何外部变量
    [&] 以引用形式使用所有外部变量
    [x, &y] x 以传值形式使用, y 以引用形式使用
    [=,&x,&y] x,y 以引用形式使用,其余变量以传值形式使用
    [&,x,y] x,y 以传值的形式使用,其余变量以引用形式使用
    “ ->返回值类型”也可以没有, 没有则编译器自动判断返回值类型。

     1 int main()
     2 {
     3     int x = 100,y=200,z=300;
     4     cout << [ ](double a,double b) { return a + b; } (1.2,2.5) << endl;
     5     auto ff = [=,&y,&z](int n) {
     6         cout <<x << endl;
     7         y++; z++;
     8         return n*n;
     9     };
    10     cout << ff(15) << endl;
    11     cout << y << "," << z << endl;
    12 }
    13 //输出:
    14 //3.7
    15 //100
    16 //225
    17 //201,301
    1 int a[4] = { 4,2,11,33};
    2 sort(a,a+4,[ ](int x,int y)->bool { return x%10 < y%10; });
    3 for_each(a,a+4,[ ](int x) {cout << x << " " ;} ) ;
    //11 2 33 4
     1 #include <iostream>
     2 #include <algorithm>
     3 #include <vector>
     4 using namespace std;
     5 int main()
     6 {
     7     vector<int> a { 1,2,3,4};
     8     int total = 0;
     9     for_each(a.begin(),a.end(),[&](int & x) {total += x; x*=2;});
    10     cout << total << endl; //输出 10
    11     for_each(a.begin(),a.end(),[ ](int x) { cout << x << " ";});
    12     return 0;
    13 }
    14 //程序输出结果:
    15 //10
    16 //2 4 6 8

    实现递归求斐波那契数列第n项:
    function<int(int)> fib = [&fib](int n)
    { return n <= 2 ? 1 : fib(n-1) + fib(n-2);};
    cout << fib(5) << endl; //输出5
    function<int(int)> 表示返回值为 int, 有一个int参数的函数

    #include <iostream>
    #include <string>
    #include <cstring>
    using namespace std;
    class String
    {
    public:
        char * str;
        String():str(new char[1]) { str[0] = 0;}
        String(const char * s) {
            str = new char[strlen(s)+1];
            strcpy(str,s);
        }
        String(const String & s) {
            cout << "copy constructor called" << endl;
            str = new char[strlen(s.str)+1];
            strcpy(str,s.str);
        }
        
        String & operator=(const String & s) {
            cout << "copy operator= called" << endl;
            if( str != s.str) {
                delete [] str;
                str = new char[strlen(s.str)+1];
                strcpy(str,s.str);
            }
            return * this;
        }
        // move constructor
        String(String && s):str(s.str) {
            cout << "move constructor called"<<endl;
            s.str = new char[1];
            s.str[0] = 0;
        }
        
        // move assigment
        String & operator = (String &&s) {
            cout << "move operator= called"<<endl;
            if (str!= s.str) {
                str = s.str;
                s.str = new char[1];
                s.str[0] = 0;
            }
            return *this;
        }
        ~String() { delete [] str; }
    };
    template <class T>
    void MoveSwap(T& a, T& b) {
        T tmp(move(a)); // std::move(a)为右值,这里会调用move constructor
        a = move(b); // move(b)为右值,因此这里会调用move assigment
        b = move(tmp); // move(tmp)为右值,因此这里会调用move assigment
    }

    int main()
    {
        //String & r = String("this"); // error
        String s;
        s = String("this");
        cout << "****" << endl;
        cout << s.str << endl;
        String s1 = "hello",s2 = "world";
        MoveSwap(s1,s2);
        cout << s2.str << endl;
        return 0;
    }
    //输出:
    //move operator= called
    //****
    //this
    //move constructor called
    //move operator= called
    //move operator= called
    //hello

  • 相关阅读:
    学校的破网,你别再掉了
    PhotoShop SDK的获取
    我的C++博客开张了
    一个新的嵌入式门户
    试用Bloglines.com
    PhotoShop的插件体系
    VB6 to VB.NET Migration Guide Community Preview #4
    看看Microsoft都买了些什么
    Borland CTO辞职
    PhotoShop插件的开发
  • 原文地址:https://www.cnblogs.com/wanderingzj/p/5345940.html
Copyright © 2020-2023  润新知