1. c++11新增long long 類型, 新增空指針nullptr類型。
2. 可尋址的最小內存塊--字節, 存儲的基本單元--字(一般由幾個字節組成)
3. 有符號和無符號作運算時,有符號會自動轉換成無符號數。
4. 變量的聲明和定義,聲明並不佔內存空間(代表類型和名字),定義的時候才分配具體的內存空間,能夠多出聲明,但只能一處定義。 注意區分初始化和賦值,初始化是變量定義的時候賦初值,賦值是將原來的值替換爲一個新值。
5. 列表初始化 & 初始化列表
列表初始化是一種初始化方式,經過大括號{xxx}來初始
初始化列表指的是一個用來初始化的列表{xxx}。
默認初始化:函數內的變量不會默認初始化,全局變量會初始化爲0,類中的變量初始化取決於類本身。
6. 顯示訪問一個全局做用域的變量-- 域運算符:: 表示全局做用域, 當外層和函數內都定義了b變量是,要使用外層的變量b則須要提供訪問方式::b
7. 引用 & 指針:
引用:
引用必須被初始化 --不能從新賦值,定義時賦值,和const相似
引用不能從新綁定新對象
引用自己是一個別名,不是一個對象(引用實質上是經過指針實現,引用的大小和指針相同,直接用sizeof求引用是求的引用對象的大小,將引用變量放到一個類中,求這個類的大小能夠求出引用自己的大小)
指針:
指針自己是一個對象
指針不用賦初值
void *能夠保存任何類型的指針,函數參數爲void *時能夠傳入任何類型的指針。
8. const修飾符
const對象必須初始化
默認狀況下,const對象僅在當前文件內有效,extern聲明後能夠跨文件(static即便extern也不能跨文件)
const和引用:(常量引用)
常量引用不只能夠引用一個很是量的左值,還能夠引用一個右值如 const int &a = 32;
還能夠引用一個非匹配類型可是能轉換成對應類型的值如 double b = 3.3; const int &a = b; 由於實際實現是將b轉成了一個臨時int對象,在用這個臨時對象給const引用賦值(利用了const引用能夠指向臨時變量的特性,也就是常量引用能夠引用右值的特性)
const和指針:
const修飾指針能夠分爲頂層const(修飾指針變量/離變量近)和底層const(修飾指針指向的內容/離變量遠) const int *const p = NULL; 前一個爲底層, 後一個爲頂層
底層const指針:表示指針指向的是一個常量對象
容許將一個指向常量的指針指向很是量,這樣不能經過這個常量指針修改這個很是量的值。
底層const修飾的是指向的對象,所以屬性和 指針、引用等符合類型的基本類型部分有關。
當進行拷貝操做時,頂層const無影響,可是底層const不可忽略
int i = 32;
const int *p1 = &i; // 底層const
int *const p2 = &i; // 頂層const
int *p3 = p2; // 頂層const無影響,能夠賦值 (能夠經過p3修改指向的內容)
int *p4 = p1; // 錯誤,底層const影響(其實能夠換個角度理解,p1底層const修飾,指向的是一個const對象,而p4是一個非底層const的指針,若是p4指向p1指向的對象,則能夠經過p4改變對象的值,這是不合理的)
頂層const指針:表示指針自己是一個常量指針
常量指針必須初始化,一旦初始化後就不能改變指針的指向。
const int a = 3; a的const是一個頂層const,由於const修飾的是左邊的a變量。
在賦值時,非const對象能夠給const對象賦值,const對象不能給非const對象賦值,在傳遞時,const對象能夠經過強制類型轉換const_cast去掉const屬性傳遞給非const對象。
9. constexpr(另外單獨寫這個修飾符的做用)
常量表達式:在編譯過程就能獲得計算結果的表達式(編譯階段就能肯定其常量值)
const int a = 39;
const int b = a + 1; // 是常量表達式,編譯階段可獲取常量值
const int sz = get_size(); // 不是常量表達式, sz自己是一個常量,可是必須在運行時才能獲取常量值
constexpr:c++11新規,將變量聲明爲constexpr類型以便由編譯器來驗證邊浪的值是不是一個常量表達式。constexpr變量必定是一個常量,而且必須用常量表達式初始化(將常量值確認時機提早到編譯階段)
constexpr int sz = get_size(); // 只有當get_size()是一個cosntexpr函數時纔是一條正確的聲明語句。
constexpr修飾函數:全部形參和返回值類型都是constexpr
constexpr和指針:constexpr修飾指針時,表示的是頂層指針,一個常量指針。(constexpr常量屬性,修飾對象自己)
10. 別名
typedef: typedef double xxx;
using: using xxxx = double;
const修飾別名:修飾的是對象自己,如 typedef double *dp; dp爲都double*指針, const dp point; const修飾的是常量指針,修飾的是指針自己,頂層指針。
11. auto: auto value = value1 + value2 根據加完的結果來推到出類型。auto變量必須賦初值。
auto會忽略頂層const,底層const會保留下來
const int a = 32; auto b = a; b會忽略a的頂層const
const int *c = &a; auto p = c; p會繼承c的底層屬性。
auto e = &a; 對常量取地址是一種底層const(指針指向的是一個常量對象:const int *p = &a)
auto &f = 32; 錯誤不能,不能引用一個字面量。
const auto &g = 32; 能夠引用一個字面量
12. decltype:c++11引入,推倒表達式的類型,相對於auto,decltype只是獲取類型,而不獲取初始值。
int a = 3;
int func() { return 3;}
decltype(a) b = a;
decltype(func()) c = b; // 編譯器並不實際調用函數func,而是使用當func調用時的返回類型。decltype(func)返回函數類型,decltype(func)* 表示函數指針。
decltype返回的類型包括全部限定,比auto更靈活
const int *p = &a; decltype(p)返回的是const *p類型
const int &b = a; decltype(b)返回的是const int &類型。
若是decltype返回的類型是引用類型,須要賦初值。
decltype(())返回的是引用類型:
decltype((a)) 返回的是 int &類型。
13. struct / class [className] {xxx; xxx; xx;} instanceName1, *pInstanceName2;
在類或者struct聲明後面直接跟名字的狀況,這種是實例對象,instanceName1是一個實例化的對象,pInstanceName2是一個實例化對象指針。
14. c++11新規定,能夠爲類中的數據成員提供一個類內初始值。
15. 頭文件一般包含哪些只被定義一次的實體,如類,const和constexpr變量。
頭文件一旦改變,包含了該頭文件的源文件都須要從新編譯
頭文件保護符:
#ifndef _XXXX_XXXX_H
#define _XXXX_XXXX_H
#endif
c++
1. using 聲明做用域:using namespace::name;
2. string
構造方法:string s1; string s2(s1); string s2 = s1; string s3("value"); string s3 = "value" string s4(n, 'c')
支持下標訪問,重載了+、==、>=、=、>>運算符,自帶empty(), size() 函數
3. 範圍for
for (auto a : str) { cout << a << endl;}
4. vector 容器
是一個類模板
構造函數:
vector<T> v1;
vector<T> v2(v1); // 拷貝副本
vector<T> v2 = v1; // 內部元素值拷貝
vector<T> v3(n, val); // n個val 若是寫成 vector<T> v3{n, val};指的是兩個值n和val
vector<T> v4(n); //n個默認值
vector<T> v5{a,b,c...}; //列表初始化 vector<T> v5(a,b,c...)這種寫法是錯誤的
vector<T> v6 = {a,b,c...}
重載了=、==、!=、<、<=等運算符 (須要內部元素提供對應操做符的重載)
提供了push_back(t),size(),empty()等函數。
能用下標方式訪問已存在元素,可是建立空間不能用下標方式,vector的內存是動態增加的(這個後面看stl在深刻),建立容器可使用初始化或者push_back自動擴容。
5. 迭代器
方便的訪問容器內的元素
容器提供的兩個函數,begin()和end(); begin返回的是指向第一個元素的指針,end()返回的是指向最後一個元素的後面一個位置;
迭代器支持指針類型訪問數據: -> 和 *
迭代器支持運算++、--、+=、+ 等,用來移動迭代器
迭代器有const版本 const_iterator,const版本迭代器不能經過迭代器改變元素。
6. 數組
不能使用數組來初始化另外一個數組,不能直接使用數組對象,可是可使用數組的指針和引用。
int arr[10] = { 0 }; int (*pArr)[10] = &arr; 數組指針 int (&pArr)[10] = arr; // 數組引用
不存在引用的數組(數組元素是引用的狀況是不會有的:引用須要初始化,引用大小怎麼肯定)
下標方式訪問數組的時候注意不要數組越界
decltype(arr)返回的是一個數組類型: decltype(arr) a = {a,b,c...};
7. 指針和數組
指針指向數組的時候指向的是第一個元素的地址。
c++11新增兩個函數begin(arr)返回指向數組的第一個元素的指針,end(arr)返回指向最後一個元素的後一個位置的指針。這兩個函數在iterator頭文件中
數組下表能夠爲負數,當指針指向數組中間位置是,能夠經過負數的下標來訪問元素
arr + 1 和 &arr + 1 是不同的。一個數元素步長移動,一個數組步長移動。
express
1. 一元運算符做用於一個運算對象,如&; 二元運算符做用於兩個運算對象如 +-*/數組
2. 左值:在等號左邊的值,表示對象的身份,有內存空間; 右值:在等號右邊,表示對象的值(不能再內存中尋址),程序運行中的中間值大部分是右值。(若可對錶達式用 & 符取址,則爲左值,不然爲右值)安全
c++11新增的右值引用&&,右值引用是用來支持轉移語義的。轉移語義能夠將資源 ( 堆,系統對象等 ) 從一個對象轉移到另外一個對象,這樣可以減小沒必要要的臨時對象的建立、拷貝以及銷燬,可以大幅度提升 C++ 應用程序的性能。消除了臨時對象的維護 ( 建立和銷燬 ) 對性能的影響。函數
3. 前置和後置++: 前置++是先++而後返回++後的對象,後置++是先++可是返回的是++前的對象。性能
對於 *beg = toUpper(*beg++) 這個表達式來講,行爲是未定義的,關鍵在於先執行右邊的++仍是左邊的*beg,若是先執行左邊的,則beg最後值會+1, 若是先執行右邊的,最後執行左邊給beg賦值(賦的值是++前的對象),beg值不會發生變化;this
4. 位運算符( & | ~ ^)和邏輯運算符(&& || !)spa
5. sizeof是個運算符而非函數,參數能夠有括號,也能夠沒有括號; sizeof int ; sizeof(int); 逗號運算符求值順序依次從左往右。.net
6. 類型轉換:指針
隱式轉換: int與double的轉換、布爾與int的轉化、 sign有符號想unsigned無符號轉換、數組轉換成指針、指針與int 0的轉化、變量轉化成常量、char *與string的轉換、
顯式轉換: c風格的 cast-name<type>(experssion) , double b = 3.33; int a = (int)b; int c = int(b);
c++四種強制轉換: static_cast , const_cast , dynamic_cast, reinterpret_cast;
備註:參考https://blog.csdn.net/u010275850/article/details/49452373 後面專題筆記梳理。
頂層const和底層const: 頂層const離變量名比較近 int *const p,修飾變量的。底層const修飾指針對象的 int const *p ;
5.1 語句
簡單語句:用;代替,最好用括號代替
符合語句:多個語句組合成的語句塊,用{ }包起來。
5.2 語句做用域:爲了不超出語句的做用範圍,用{}把語句包起來,哪怕是空語句
5.3 條件語句:
if else:注意垂懸else的狀況,避免方法是顯示的代表做用域,經過{ }將if和else後的範圍包起來。
switch case:注意每一個分支後的break;case後必須是整形的常量表達式; default能夠處理非正常case的異常狀況。
5.4 迭代語句:
while:不明確循環次數的時候使用
for:傳統for循環 for( ; ; ) { }
for:範圍for循環, c++11引入, for(declaration : expression) { } , 能夠結合auto使用
do while: 和while相比,do中的代碼塊至少執行一次。
5.5 跳轉語句
break, continue, goto(goto label; label:xxxx;),return
5.6 try catch 異常處理
能夠throw一個異常對象,異常對象能夠在標準庫中選如throw runtime_error("xxxx"), 也能夠繼承異常類。
沒有finally處理分支。
常見的異常類:exception,runtime_error,range_error, overflow_error,underflow_error,out_of_range
6.1 函數基礎
函數調用,控制權轉換,形參與實參,參數的列表,返回的類型,局部對象的生命週期,函數聲明和定義,分離式編譯
返回類型不能是數組和函數類型,可是能夠返回數組的指針和函數的指針。
局部靜態變量,只在第一次調用的時候初始化,直到程序結束才被銷燬。
函數能夠多處聲明,可是隻能定義一次。
6.2 參數傳遞
1 值傳遞:要修改外部數據,能夠值傳遞指針來修改。若是是對象,會發生拷貝構造。
2 引用傳遞:直接引用外部變量,當這個變量至關大的時候,能夠替換爲這個變量的地址,值傳遞地址。
3 const形參:傳入的值能夠是const,也能夠是非const。const形參和非const形參不能同時出現,不是重載,在編譯的時候編譯出來的名字同樣。若是函數只是傳遞一個參數而不改變參數的值,儘可能使用常引用傳值。(對於指針來講,底層const和無底層const修飾的形參是重載,引用const和非const是重載)
const修飾引用或者底層const指針的時候,是重載
const修飾非引用,非指針時,不是重載。修飾頂層const也不是
4 數組形參:數組形參會被當作一個變量指針。形參能夠定義成數組的引用,注意不是引用數組;
引用數組指的是數組裏的每一個元素都是引用;引用數組是非法的。
引用是個別名,沒有內存空間,編譯器也不知道給引用數組分配多少內存,引用元素定義出來就要賦初值,在數組中意味着定義一個引用數組立刻就要給全部的元素賦值。
參數不能是數組,能夠是數組的指針或者引用。
5 可變參數:(後面專題梳理,包括decltype的用法)
c++繼承c的可變參數:省略符,只能出如今參數的最後一個位置。
c++11新增的兩種:若是參數類型相同,使用initializer_list; 若是參數類型不一樣,使用可變參數模板
initializer_list: 表示特定類型值得數組
聲明: void func(initializer_list<stirng> ls) 調用:func( { "xxx", "zzz", "eee"} )
6.3 返回類型和return語句
1. 無返回值函數 void
2. 有返回值的函數:
注意不要返回局部對象的引用和指針
能夠返回數組指針和函數的指針
能夠返回左值(vector和string的元素)
能夠返回列表初始化,外面用容器接受,就像調用可變參數同樣,裏面用initializer_list接收,調用的時候調用列表{ }。
3 返回數組指針或者數組引用:
直接寫起來可能比較複雜,可使用typedef int arr[10]或者 using arr = int [10] 來表示數組的別名;
arr * func() { } 返回一個數組 等價於 int (*func( ))[10] { }
也可使用c++11新增的尾置返回類型: auto func() -> int (*)[10] { } 使用auto代替返回值,具體的使用->後面代替。
若是有類型類似的對象,可使用decltype來替換: decltype(arr ) * func() { } (decltype出來的是類型,須要加上*)
6.4 函數重載
形參的數量和類型不一致,函數名一致的函數爲重載函數
返回值類型不在考慮範圍內,頂層const形參也不在考慮範圍內 (頂層const表示的是離變量近的const),const非指針非引用也不是
重載與做用域:若是函數內部重載了函數外部的同名函數,函數外部的同名函數在函數內就不可見了,即便是不一樣參數和類型的同名函數。這個時候在函數內部調用同名的外部重載函數會調用失敗。強行匹配函數內部的同名函數
6.5 特殊用途的語言特性
1. 默認參數:默認參數必須出如今全部參數的末尾位置。給定的默認實參在函數聲明的時候只能出現一次,多出函數聲明的地方不能每一個地方都對同一個函數參數賦默認值。 int func (int a , int b = 1);下一個聲明的地方只能是 int func( int a = 1, int b),不能再次對b作默認參數聲明。默認參數在構造函數上時須要注意用explicit來修飾構造函數,由於默認參數可能致使單參數發生隱式轉換。
2. 內聯函數:編譯過程內聯展開。內聯不必定能成功,編譯器能夠忽略這個請求。內聯函數通常放在頭文件內。頭文件和源文件任意聲明瞭inline都行。
3. constexpr函數:指的是能用於常量表達式的函數。編譯階段就確認常量屬性。const修飾可能會拖到運行階段。
函數的返回類型及全部形參都得是字面值類型。函數體中必須只用一條return語句。返回的不必定是常量表達式
constexpr函數被隱式的定義成內聯函數。constexpr函數放在頭文件內。
4. 調試幫助:
assert預處理宏 、NDEBUG與處理變量。能夠在編譯的時候加入這個編譯選項,也能夠在文件中定義#define NDEBUG;
__FILE__: 文件名的字符串字面值
__LINE__: 當前行號
__TIME__:文件編譯時間
__DATE__:文件編譯日期
6.6 函數匹配
候選函數:函數名、可調用
可行函數:參數類型和個數匹配,或者類型可以轉換後匹配
最優函數:參數嚴格匹配比例最高。
6.7 函數指針
函數指針能夠直接用函數名賦值,也能夠取函數名的地址來賦值。調用方式也能夠直接fun() 也能夠解引用 (*func)()
函數聲明的時候若是某個參數爲函數指針,直接將聲明形式定義在參數位置便可,會轉換成函數指針,相似於數組。也能夠取別名後的函數指針。取別名可使用typedef,using,decltype和尾置類型的方法。
7.1 定義抽象數據類型
1. this:成員函數經過一個名爲this的額外隱式參數來訪問調用它的那個對象。在成員函數後面加上const,const修飾的是this指針;
this指針自己是個常量指針,底層const修飾後,成了指向常量的常量指針
成員函數中的隱式this參數:T* const this; 當成員函數修飾尾置const後,成員函數不能改變類的成員,其實就是修飾的this指向的對象,因此隱藏的this指針形式爲 const T* const this;
const修飾後的this指向的對象也是常量,const修飾後的函數不能修改對象中的數據。
成員函數後面加const後,這個函數的隱式對象爲常量對象,此時在const函數內部就不能調用非const的函數了。(常量成員函數)
const成員函數不能調用非const成員函數,若是確實要調用,使用 const_cast強轉*this對象爲非const對象。
在函數內返回*this表示返回調用這個函數的對象自己。const成員函數以引用的形式返回的*this是常引用。
2. 構造函數
構造函數不能聲明爲const的,當咱們建立類的一個const對象時,直到構造函數完成初始化過程後,對象才能真正的獲取到其「常量」屬性,構造函數在const對象的構造過程當中能夠向其寫值。
只有當類沒有聲明任何構造函數時,編譯器纔可能會自動地生成默認構造函數,生成默認構造函數的前提條件式類中的全部成員都可以默認的生成初始值或者提供初始值,若是類中含有自定義類型而且這個類型沒有提供默認構造函數,那麼這個類就不能生成默認的構造函數。
c++11的新標準,若是要顯示的使用默認構造函數,在構造函數後面加上 =default ; default表示使用編譯器默認的構造函數,在聲明的構造函數後面加上=default表示內聯,也能夠在源文件中加=default;
構造函數的初始值列表: 類(): a(0),b(222),c("sss") { } ; a、b、c就是構造函數的初始值列表。
7.2 訪問控制與封裝
1. struct的默認訪問屬性是public, class的默認訪問屬性是private
2. 友元:類的友元函數或者友元類能夠訪問類的全部成員,友元函數或者友元類能夠聲明在類的任何位置,而且在類中聲明友元只是起了一個權限指定的做用,代表能夠友元能夠訪問類中的成員,並非一般意義上的函數或者類聲明。若是要調用友元,仍是要在其餘頭文件或者某個地方聲明函數。友元函數在外部實現的時候能夠在內部定義一個類對象,也能夠在參數中使用這個類類型參數。函數聲明最好和友元類放在同一個頭文件中。
3. 友元關係不具有傳遞性,子類不繼承友元關係。每一個類本身控制本身的友元類和友元函數。
4. 把某個類的成員函數聲明成一個類的友元函數時,在類中聲明友元的時候須要帶上本身的類做用域: friend void classxxx::func();
5. 友元函數能夠在類中聲明友元的時候順便定義出來,可是在隨後的類成員函數使用時,必須顯示的在類的外面再次聲明。理由是在類的內部聲明友元friend,只是代表了這個函數能夠訪問類中的全部成員,可是這個函數對這個類來講不可見。因此必須顯示的在外面聲明這個函數。
7.3 類的其餘特性
1. 起別名: typedef std::string::size_type pos; 或者 using pos = std::string::size_type
2. 內聯: default修飾的構造函數是隱式內聯的,在類的頭文件中聲明並定義的函數是隱式內聯的,在頭文件用inline修飾的函數是顯示內聯的,在源文件中也能夠用inline來修飾函數表示內聯。
3. mutable:在類中,const修飾的函數不能改變類的成員,可是若是類成員經過mutable修飾後,也能在const常量成員函數中修改這個mutable成員。
4. const成員重載,這裏注意區分const參數和const修飾的成員函數,const修飾的成員函數和非const是兩個不一樣的函數,const修飾的成員函數優先匹配常量類對象。
const修飾的指針或者引用參數時,若是是頂層const,const和非const版本是同一個函數。若是是底層const,則爲重載版本。
const修飾的是值類型的參數是,非const和const版本是同一個函數,不會發生重載
5. 類的前向聲明:就是把類提早聲明瞭,在後面再定義類,在定義類以前,可使用類名指針或者引用,用在參數或者返回值處,但毫不能定義實體對象。(編譯器沒法構造對象,不知道分配多少內存)
鏈表中應用了前向類,類對象表示一個節點,下一個節點每每就是本身的類型指針,這個時候類中包含本身的類型指針。
7.4 類的做用域
1. 類的成員函數的返回值類型若是是類中定義的類型,則在源文件定義這個類成員函數的時候,返回的值類型前面必須顯示的寫出做用域。
class::item class::func () { } 顯示的代表item的做用域。
2. 類的解析:首先編譯成員的聲明,直到類所有可見以後才編譯函數體。
3. 取別名重定義:若是在前面已經使用了typedef對某個類型去了一個別名如nameA,後面就不能再對其餘類型或者本類型取一個一樣名字nameA的別名。
4. 全局做用域運算符::
在類中若是定義了一個變量和類外的一個變量同名,類中的這個變量會覆蓋外部的變量,訪問的時候會默認訪問類中的變量,這個時候若是要訪問外部的變量,之間用::name 訪問外部的變量。
7.5 類的構造函數
1. 構造函數的初始值列表: 注意和參數列表名字區分。
若是類成員有const或者引用的時候,必須使用初始值列表來初始化。const和引用的屬性是聲明就初始化,初始化一次。
初始化列表和構造函數內值的區別:初始化列表是直接初始化數據成員,構造函數內賦值是先經歷了初始化,在進行賦值,在效率上不如初始化列表。
初始化列表的初始化順序和成員數據的定義順序有關,和列表的初始化順序無關。因此儘量讓成員數據和初始化列表順序一致。
2. 委託構造函數:委託構造函數就是使用類的其餘構造函數來執行本身構造函數的初始化過程。非const版本的構造函數使用const版本的構造函數來委託。
定義一個基本的構造函數,後面的構造函數的初始化能夠調用以前的構造函數
class (int a, string s, double b) : a(a), s(s), b(b) {}
class (int a , string s) : class(a, s, 0.0) { }
class (int a, string s, double b, string d) : class (a, s , b) , d(d) { }
3. 隱式的類的類型轉換 explicit : 構造函數只有一個參數,這個參數類型的變量值能夠隱式的轉換成一個類對象。(只對一個參數的構造函數有效)
string ss = "xxxx", 此時「xxxx」是一個char *類型的字符串,可是string類型的構造函數之一能夠接受char*,這個時候「xxxx」就被隱式的轉換成了string(‘’xxxx"),而後給ss賦值。
抑制構造函數的隱式轉換,能夠在單一參數的構造函數前面加上explicit,這樣調用string ss = 「xxxx」就會失敗,只能顯示的轉換string ss = string("xxxx"),或者使用強制類型轉換
多參數的構造函數若是提供了默認參數也會發生隱式的類類型轉換。
string ss = static_cast<string>("xxxx");
4. 聚合類:全部成員都是public,沒有任何構造函數,沒有類內初始值,沒有基類也沒有virtual,相似一個struct,用來保存數據
5. 字面量常量類: