码迷,mamicode.com
首页 > 编程语言 > 详细

C++ 11 新特性

时间:2016-04-01 20:14:47      阅读:273      评论:0      收藏:0      [点我收藏+]

标签:

一.统一的初始化方法

 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

C++ 11 新特性

标签:

原文地址:http://www.cnblogs.com/wanderingzj/p/5345940.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!