亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++11的新特性簡單匯總介紹 (二)

2020-05-23 14:01:43
字體:
來源:轉載
供稿:網友

1. 范圍for語句

C++11 引入了一種更為簡單的for語句,這種for語句可以很方便的遍歷容器或其他序列的所有元素

vector<int> vec = {1,2,3,4,5,6};for(int x: vec){  cout<<x<<endl;}

2. 尾置返回類型

要想引入尾置類型,我們還得從復雜的類型聲明說起。如果我們需要定義一個含有10個int元素的數組,一般是這樣的:

int arr[10] = {0};

如果要定義指向這個數組的指針呢:

 

復制代碼 代碼如下:

int (*p_arr)[10] = &arr; //注意:int *p_arr[10] 表示一個數組,有10個元素,元素類型是int*

 

如果要定義一個函數,這個函數接受一個char類型的參數,并返回一個指向10個int類型數組的指針呢:

 

復制代碼 代碼如下:

int (*func(char x))[10];

 

這樣的聲明是不是看的頭都大了,其實我們可以簡化一點,一般情況下我們可以使用別名進行簡化,比如:

 

復制代碼 代碼如下:

typedef int ARR[10] ; // 定義一個類型 ARR這是一個數組類型,含有10個int類型的元素
using ARR = int[10] ; // 同上

 

再定義如上的函數:

 

復制代碼 代碼如下:

ARR * func(char x) ; // 函數返回的類型是 ARR* 也就是指向具有10個int元素數組的指針

 

當然在C++11中我們可以用之前講到過的另外一個關鍵字decltype:

 

復制代碼 代碼如下:

decltype(arr) * func(char x) ; // decltype(arr)表達式會獲得arr的類型

 

最后就輪到我們本節要說的C++11的另外一個特性,尾置返回類型,任何函數都可以使用尾置返回類型,這種形式對于返回類型比較復雜的函數最有效,比如上面的函數可以使用如下方式:

 

復制代碼 代碼如下:

auto func(char x) -> int(*) [10];

 

這種形式將函數的返回類型寫在函數聲明的最后面,并且在函數形參列表后面加上 -> 符號,然后緊接著是函數需要返回的類型,由于函數的返回類型被放在了形參列表之后,所以在函數名前面使用一個 auto替代。

3. =default 生成默認構造函數

在C++的類中,如果我們沒有定義構造函數,編譯器會為我們合成默認的無參構造函數,如果我們定義了構造函數,則編譯器就不生成默認構造函數了,但是如果我們定義構造函數同時也希望編譯器生成默認構造函數呢? C++11中可以通過在構造函數的聲明中直接  =default的方式要求編譯器生成構造函數。

class ClassName{  public:    ClassName(int x);    ClassName()=default; // 顯示要求編譯器生成構造函數};

4. 類對象成員的類內初始化

class ClassName{    public:        int x = 10; //C++11 之前是不允許的};

5. lambda表達式與bind函數

lambda表達式是一個可以被調用的代碼單元,相當于一個內聯函數,有參數和返回值以及函數體。但是跟函數不同的是,lambda表達式可以定義在函數的內部,一個完整的lambda表達式具有如下形式:

[捕獲列表](參數列表) mutable -> 返回類型 {函數體}

int x = 10;int y = 20;auto f = [x,&y](int a ,int b){++y;return a+b+x+y;};cout<<f(1,2)<<endl; //34cout<<y<<endl;   //21

lambda可以省略參數列表(如果沒有參數的話),可以省略返回類型,但是不能省略捕獲部分與函數體部分,即使捕獲列表為空,也要有一個空的[],lambda有兩種捕獲,一種是值捕獲,一種是引用捕獲。如果是值捕獲那么lambda中獲得的是捕獲的變量的副本,如果是引用捕獲則獲得的是引用,可以在lambda內部修改引用的變量的值,如上x是值捕獲,y是引用捕獲,lambda中默認是值捕獲,如果變量前面添加&則是引用捕獲,另外lambda中還有兩種形式的引用捕獲,例如[=]表示值捕獲所有可見的變量,而[&]則表示引用捕獲所有可見變量。如果希望值捕獲所有可見變量,但是又有個別變量采用引用捕獲呢,[=,&x]表示值捕獲所有可見變量,同時引用捕獲x。而[&,x]則表示引用捕獲所有可見變量,x采用值捕獲的方式。

有關bind函數,在很多地方我們可以使用函數替換lambda表達式,畢竟如果很多地方需要用到同一個lambda表達式,而且這個lambda表達式比較長的話,將其定義成函數應該是最好的。對于沒有捕獲列表的lambda表達式我們可以直接使用函數替代,例如:

void main(){  auto f=[](int x,int y){return x+y};  f();}

我們可以用下面的方式替代:

int f(int x,int y){  return x+y;} void main(){  f();}

與上面的lambda是等價的,但是對于有捕獲列表的lambda表達式應該怎么處理呢,例如:

void main(){  int x = 10;  int y = 20;  auto f = [x,&y](int a ,int b){return a+b+x+y;}; //一個值捕獲,一個引用捕獲  f(33,44);}

如果轉換成函數的形式:

int x = 10;int y = 20;int f(int a,int b){ return a+bx+y;} void main(){  f(33,44);}

這是一種可行的方法,但是總不能把所有的捕獲變量定義成全局變量吧?,F在的關鍵問題是lambda的捕獲表達式中的內容轉換成函數不可行,C++11提供了bind函數來完成這樣的操作。

#include <functional> //bind()#include <iostream>using namespace std;using namespace std::placeholders; // _1,_2所在的命名空間int f(int x,int y,int a,int b){ return a+b+x+y;} void main(){ int x = 10; int y = 20;  auto f_wrap = bind(f,x,y,_1,_2); cout<<f_wrap(33,44)<<endl; // _1,_2是占位符,表示調用f_wrap的時候_1是第一個參數,_2是第二個參數。最終會被替換成調用 f(10,20,33,44)}

如果引用類型的捕獲怎么做呢,看下面的例子,用lambda是這樣的:

#include <iostream>#include <functional>using namespace std;using namespace std::placeholders;void main(){ int x = 10; ostream &o = cout; auto f =[&o](int a){o<<a<<endl;}; // 注意這里的輸出對象是用的引用捕獲 f(x);}

使用bind是這樣的:

#include <iostream>#include <functional>using namespace std;using namespace std::placeholders;void f(ostream &o,int x){ o<<x<<endl;}int main(){ int x = 10; auto f_wrap = bind(f,ref(cout),_1); //將變量的引用傳遞到bind中是個問題,為此C++11提供了ref()函數用于獲得引用 f_wrap(x); return 0 ;}

6. 智能指針share_ptr,unique_ptr

C++11中引入了幾種智能指針,智能指針能夠自動釋放所指向的對象,其中shared_ptr允許多個指針指向同一個對象,unique_ptr則獨占所指向的對象,我們主要說明shared_ptr的使用。通過使用make_shared<type>()函數產生智能指針對象。

 

復制代碼 代碼如下:

shared_ptr<int> p = make_shared<int>(40); // p指向一個值為40的int對象
shared_ptr<string> p2 = make_shared<string>(10,'c'); //指向值為'cccccccccc'的string對象

 

make_shared<type>()函數中傳遞的值要與對應的type的構造函數相匹配,實際上應該就是直接調用的對應type的構造函數。

我們可以使用new初始化的指針來初始化智能指針:

 

復制代碼 代碼如下:

share_ptr<int> p (new int(40));
p.get(); // 使用share_ptr<type>的get()函數來獲得其關聯的原始指針。

 

shared_ptr對象在離開其作用域(例如一個函數體),會自動釋放其關聯的指針指向的動態內存,就像局部變量那樣。另外多個shared_ptr可以指向一個對象,當最后一個shared_ptr對象銷毀的時候才會銷毀其關聯的那個對象的動態內存。這里使用了引用記數。

7. 右值引用與move調用,移動構造函數

為了支持移動操作,C++11中使用了一種稱為右值引用的類型。移動操作是什么呢,一般情況下我們將一個對象賦值給另一個對象的時候會調用對象到拷貝構造函數或者拷貝賦值運算符。而移動構造函數和移動賦值運算符則用來將數據從一個對象移動到另一個對象。在很多情況下對象拷貝之后需要被銷毀,此時使用移動操作會大幅提高性能。右值引用被使用之后,其關聯的對象會被銷毀。右值引用使用兩個&&表示,例如 int && 表示右值引用,而int &則是左值。通過C++11標準庫提供的函數 std::move()可以得到某一對象的右值引用。

 

復制代碼 代碼如下:

TestClass::TestClass(TestClass &&t) noexcept //移動構造函數不應該拋出任何異常
:x(t.x),y(t.y),z(t.z),p(t.p)
{
  t.p=nullptr; // 實現移動操作之后需要保證被移動的對象的析構是安全的,所以源對象的指針成員置為空,隨后t的析構函數將會被自動調用,t被銷毀。
}

 

8. function

C++11中提供了名為function的標準庫類型,定義在頭文件<functional>中,該類型用來存儲一個可調用的對象,統一了所有可以像函數一樣調用的調用形式,例如:

#include <functional>#include <iostream>using namespace std; int add(int x,int y){  return x+y;} class Add{  public:    int operator()(int x,int y)    {      return x+y;    }}; void main(){ //function模版的參數是函數調用形式,包括返回類型,以及參數列表個數和類型  function<int(int,int)> f1 = add; //函數指針  function<int(int,int)> f2 = Add(); // 可調用類對象  function<int(int,int)> f3 = [](int x,int y){return x+y;}; //lambda表達式     cout<<f1(10,20)<<" "<<f2(30,40)<<" "<<f3(50,60)<<endl;}

9. 其他新增類型(array,forward_list,bitset,regex)

實際上C++11中除了一些語法特性新增之外,還增加了一些新的庫。例如array相當于我們傳統使用的定長數組,支持隨機訪問,不能添加刪除元素,不可以像vector一樣增長,使用array比傳統數組更加安全。

forward_list是C++11中增加的單向鏈表

regex則是C++11中新增的正則表達式

10. 總結

C++11中增加了一些庫,庫本身的使用不做過多介紹,可以參考C++標準庫/STL源碼剖析,這都是用單獨的大部頭書籍講解的,有些特性和庫是我感覺比較驚艷的,例如:

  1. auto 定義:可以讓編譯器自動推算定義的變量類型,而不需要寫長長的一串類型,特別是在含有迭代器的類型上。
  2. decltype :可以根據已知的變量來定義一個跟該變量一樣的類型。
  3. lambda:個人認為這是C++11中增加的最驚艷的特性之一,對應的還有bind()函數,其實這些內容是從Boost中來的。
  4. 智能指針:shared_ptr 雖然在以前的C++中有類似auto_ptr的智能指針,但是auto_ptr有一些缺陷并不算很好用。
  5. function類型:標準庫的function類型定義了一種可調用對象,該類型統一了所有可以當作函數一樣調用的調用形式,例如lambda,函數指針,重載了函數調用運算符()的類對象等,該特性也是參考了Boost庫。
  6. regex庫:C++11中總算有了方便的regex可以使用了。
 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美性色视频在线| 中文字幕亚洲一区| 欧美中文在线视频| www.午夜精品| 久久国内精品一国内精品| 国产精品久久一区| 国产精品久久久久av| 97在线视频国产| 26uuu国产精品视频| 粗暴蹂躏中文一区二区三区| 国产一区二区黑人欧美xxxx| 久久国产精品久久久久久久久久| 国产一区二区视频在线观看| 亚洲男人的天堂在线播放| 欧美成人三级视频网站| 亚洲一区二区三区xxx视频| 亚洲淫片在线视频| 亚洲欧洲国产伦综合| 久久影视电视剧凤归四时歌| 亚洲欧美日韩在线高清直播| 日韩精品免费电影| 日韩亚洲成人av在线| 日韩欧美在线视频日韩欧美在线视频| 久久亚洲成人精品| 亚洲最大福利视频网| 欧美乱妇40p| 亚洲第一区中文99精品| 性金发美女69hd大尺寸| 亚洲aⅴ男人的天堂在线观看| 日韩精品免费在线观看| 精品久久久久久久久久久久久久| 国产精品白丝av嫩草影院| 俺去啦;欧美日韩| 国产精品福利无圣光在线一区| 亚洲影影院av| 中国日韩欧美久久久久久久久| 亚洲精品一区中文字幕乱码| 国产最新精品视频| 精品中文字幕视频| 色av吧综合网| 亚洲精品美女免费| 亚洲国产欧美久久| 麻豆乱码国产一区二区三区| 中文字幕日韩免费视频| 亚洲级视频在线观看免费1级| 亚洲国产日韩欧美综合久久| 992tv在线成人免费观看| 亚洲系列中文字幕| 日韩网站在线观看| 久久成年人免费电影| 亚洲国产精品推荐| 欧美精品午夜视频| 亚洲午夜国产成人av电影男同| 国产精品高清网站| 成人久久精品视频| 亚洲黄在线观看| 亚洲国产日韩精品在线| 久久99久久99精品免观看粉嫩| 不卡在线观看电视剧完整版| 国产精品久久久久一区二区| 91精品在线看| 色综合久久中文字幕综合网小说| 91国内免费在线视频| 久久影院资源站| 欧美性猛交xxxx乱大交蜜桃| 国产91在线播放| 中文字幕成人精品久久不卡| 欧美最猛黑人xxxx黑人猛叫黄| 精品欧美激情精品一区| 日韩高清人体午夜| 欧美激情视频一区二区| 久久久午夜视频| 欧美孕妇与黑人孕交| 国产盗摄xxxx视频xxx69| 成人黄色在线观看| 日韩av免费在线观看| 日韩av色综合| 亚洲第一精品夜夜躁人人躁| 国产成人极品视频| 上原亚衣av一区二区三区| 亚洲成人性视频| 91国偷自产一区二区三区的观看方式| 亚洲女人被黑人巨大进入| 91系列在线播放| 亚洲精品www久久久久久广东| 欧美午夜激情在线| 夜夜躁日日躁狠狠久久88av| 国产精品成人aaaaa网站| 日韩av在线网页| 日本久久精品视频| 国产视频精品在线| 久久久午夜视频| 亚洲精品美女网站| 亚洲tv在线观看| 亚洲成人性视频| 国产亚洲综合久久| 亚洲欧美一区二区三区四区| 久久久久久亚洲精品| 91精品视频在线看| 久久精品中文字幕免费mv| 欧美成年人视频| 91免费精品视频| 91精品中文在线| 中文字幕av一区中文字幕天堂| 尤物精品国产第一福利三区| 最近2019中文字幕第三页视频| 亚洲香蕉在线观看| 日韩视频在线观看免费| 国产一区二区在线播放| 国产精品久久久| 国产精品99久久久久久久久久久久| 日本一区二区在线播放| 日韩av色在线| 国产亚洲精品美女久久久久| 国产日韩在线精品av| 久久人91精品久久久久久不卡| 亚洲精品视频网上网址在线观看| 日韩精品免费在线| 亚洲一区av在线播放| 亚洲欧美日韩网| 日韩美女主播视频| 欧美激情精品久久久久久黑人| 日本亚洲欧洲色α| 成人黄色在线免费| 波霸ol色综合久久| 欧洲成人午夜免费大片| 精品国产成人av| 91在线免费看网站| 亚洲色图25p| 久久中文久久字幕| 久久久免费观看视频| 九九热这里只有精品6| 久久影视电视剧凤归四时歌| 色青青草原桃花久久综合| 亚洲网址你懂得| 欧美成人在线网站| 亚洲福利小视频| 久久久久国产精品免费网站| 在线视频日韩精品| 欧美另类69精品久久久久9999| 久久成人av网站| 亚洲精选一区二区| 91视频8mav| 国产精品吴梦梦| 色久欧美在线视频观看| 国内精品久久久久影院优| 久久亚洲精品一区二区| 91久久久久久久一区二区| 亚洲综合在线做性| 国产在线一区二区三区| 精品无人区乱码1区2区3区在线| 亚洲久久久久久久久久| 亚洲国产一区二区三区在线观看| yw.139尤物在线精品视频| 97国产一区二区精品久久呦| 国内精久久久久久久久久人| 国产视频999| 国产一区视频在线| 国产精品亚洲视频在线观看| 欧美一区二区三区精品电影| 亚洲欧洲国产伦综合| 欧美午夜片欧美片在线观看| 国产精品私拍pans大尺度在线| 日韩成人激情视频|