目錄
- 統一的初始化方法
- 成員變數可以賦予默認初始值
- auto自動型別關鍵字
- decltype關鍵字
- 基于范圍的for回圈
- 智能指標shared_ptr
- 空指標nullptr
- 無序容器(哈希表)
- Lambda運算式
- 右值參考T&&和move移動語意
- 正則運算式
- 強制型別轉換
- 例外處理
- 運行時型別檢查
統一的初始化方法
-
通過花括號實作各類變數初始化(允許花括號嵌套)
int arr[3]{1,2,3}; vector<int> iv{1,2,3}; map<int,string> mp{{1,"hello"},{2,"world"}}; int *p=new int[20]{1,2,3}; //前三個變數初始化為1,2,3,其余用默認建構式初始化 struct A{int i,j; A(int m,int n):i(m),j(n){}} A func(int m,int n){return {m,n};} A* pa=new A{2,3};
成員變數可以賦予默認初始值
- 示例
class A{ public: i=5; }
auto自動型別關鍵字
-
定義變數時,通過所賦予的值在編譯時自動判斷變數型別
-
可用于模板回傳值,提升模板靈活性
template<class T1,class T2> auto Func(T1 x,T2 y)->decltype(x+y){ return x+y; } //auto可以不為T1、T2中的一種,->decltype(x+y)回傳值型別宣告也可省略
decltype關鍵字
-
用于獲取變數或運算式回傳值型別
-
雙括號回傳相應型別的參考
int i; decltype(i) x=5; decltype((i+x)) y=x;
基于范圍的for回圈
-
格式:
for(元素型別 i:陣列等名) -
獲取時元素,而非指標
int ary[]{1,2,3,4,5}; for(int &e:ary) e*=2; for(int e:ary) cout<<e<<endl; //2,4,6,8,10 map<int,string> mp{{1,"A"},{2,"B"}}; for(auto &e:mp) cout<<e.first<<" "<<e.second<<endl;
智能指標shared_ptr
-
需要頭檔案
<memory> -
寫法:shared_ptr
ptr(new T); -
自動托管指標,程式結束或托管數為0時自動釋放new動態分配的記憶體
-
多個shared_ptr物件可以同時托管一個指標,系統會維護一個托管計數
-
不能用于托管指向動態分配的陣列
-
創建后的指標用法與一般指標相同
int *p=new int,*p2=new int{1}; shared_ptr<int> sp1(p); shared_ptr<int> sp2(sp1); sp2.reset(); //清空sp2 sp2.reset(p2); //會置托管計數為1,只能用于智能指標第一次指向p2區域,否則可能出錯(delete多次) sp2=sp1; p2=sp1.get(); //get函式獲取地址
空指標nullptr
-
與NULL和0的區別:包含型別,能夠轉換位bool型,卻不能轉化為整型
-
可以直接和NULL和nullptr比較
-
不同型別的指標不能比較(如double*和int* 型)
int *p1==NULL,*p2=nullptr; shared_ptr<double> p3=nullptr; if(p1==p2) cout<<"Equal\n"; //相等 if(p3==NULL) cout<<"Equal\n"; //相等 if(p3==nullptr) cout<<"Equal\n"; //相等 bool b=nullptr; //b=false int i=nullptr; //錯誤?
無序容器(哈希表)
unordered_map- 使用與map類似
- 插入、查找元素的時間復雜度幾乎為常數,但空間占用較多
Lambda運算式
-
[外部變數范圍方式說明符](形參表)->回傳值型別{ 陳述句組 }
"->回傳值型別"也可以沒有,由編譯器自動判斷外部變數訪問符 含義 [] 不使用任何外部變數 [=] 以傳值方式使用外部變數 [&] 以參考方式使用外部變數 [x,&y] 傳值方式使用x,參考方式使用y [=,&x,&y] 參考方式使用x,y,傳值方式使用其他變數 [&,x,y] 傳值方式使用x和y,參考方式使用其他變數 -
示例
cout<<[](double x,double y){return x+y;}(1.1,2.2)<<endl; //3.3 int x=100,y=200; auto ff=[&x,&y](int n){ x++;y++; return n*n; } cout<<ff(15)<<" "<<x<<" "<<y<<endl; //225 101 201 function<int(int)> fib=[&fib](int n){return n<=2?1:fib(n-1)+fib(n-2);} //無法由回傳值確定回傳型別,不能用auto,第一個int代表回傳值,第二個int代表函式形參表 cout<<fib(5)<<endl; sort(arr,arr+5,[](int a,int b){return a<b;});
右值參考T&&和move移動語意
-
詳見 參考資料
-
C++中所有的值都必然屬于左值、右值二者之一,左值是指運算式結束后依然存在的持久化物件,右值是指運算式結束時就不再存在的臨時物件,所有的具名變數或者物件都是左值,而右值不具名,很難得到左值和右值的真正定義,但是有一個可以區分左值和右值的便捷方法:看能不能對運算式取地址,如果能,則為左值,否則為右值, -
目的:提高程式運行效率,減少需要深拷貝的物件的深拷貝次數(通過直接奪取變數已分配動態分配空間)
-
具體型別:
左值參考, 使用T&, 只能系結左值右值參考, 使用
T&&, 只能系結右值常量左值, 使用
const T&, 既可以系結左值又可以系結右值已命名的右值參考,編譯器會認為是個左值
編譯器有回傳值優化,但不要過于依賴
-
移動建構式 和移動賦值函式,如
String(String&& str)和String& operator= (String&& str) -
std::move()用于告訴編譯器盡量將該變數當成右值處理,不存在移動拷貝、移動賦值時再考慮普通方式 -
Dev C++中,return區域物件,對導致優化,不呼叫移動或復制建構式
-
可移動但不可復制的物件:
struct A{ A(const A& a)=delete; A(const A&& a){cout<<"Move Constructor."<<endl;} A(){} }
正則運算式
-
需包含
<regex>頭檔案 -
示例:
regex reg("\\d{3}{[a-zA-Z]+}.(\\d{3}|N/A)\\s\\1"); //在C/C++中反斜杠必須寫2個以反義 cout<<regex_match("123Hello N/A Hello",reg)<<endl; //輸出1,匹配成功 string s("123Hello N/A hello"); cout<<regex_match(s,reg)<<endl; //輸出0
強制型別轉換
- static_cast
- 用于比較“自然”和低風險型別的轉換,如整型與字符型、浮點型的轉換
- 不能用于不同型別指標、參考轉換,或整型與指標的轉換
- reinterpret_cast
- 用于不同型別指標、參考的轉換,以及指標和能容納下指標的整數型別的轉換,執行逐個位元拷貝的操作
- 不進行型別檢查
- const_cast
- 用來去除const屬性,將const指標、參考轉為同型別非const型別參考
- dynamic_cast
- 專門用于將多型基類指標或參考轉換成派生類指標、參考,
- 對于不安全的指標轉換(指標不是指向派生類物件),轉換結果等于NULL
- 對于不安全的參考轉換,拋出bad_cast例外
例外處理
-
在
try中進行可能例外的操作,將例外傳遞給catch -
throw主動拋出例外 -
catch捕獲try傳遞的例外,可以存在多個catch函式,從上到下對例外進行型別匹配,catch(...)表示匹配任意型別 -
發生例外后,try范圍內后續命令不再執行,直到例外被捕獲
-
如果例外未在函式內部處理,就會被拋給上一級的函式
-
常見的例外類(從exception類派生而來,位于
<stdexcept>中,型別例外位<typeinfo>中out_of_range如vector、string用at函式范圍越界時bad_alloc動態分配記憶體請求失敗(typeinfo頭檔案中)bad_cast用dynamic轉換基類參考失敗(typeinfo頭檔案中)
--> 通過例外物件的what()函式獲取例外資訊
運行時型別檢查
-
需要
<typeinfo>頭檔案 -
對于多型類,會回傳實際指向的物件型別
-
示例
long n; cout<<typeid(n).name()<<endl;
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/42988.html
標籤:C++
上一篇:第九章 STL標準庫(二)
下一篇:c++中的多型機制
