1. 程式人生 > 其它 >c++讀書筆記

c++讀書筆記

陣列名和指標 不一樣的點,陣列名是常量,不可用於 arrayname=arrayname+1運算。  陣列名sizeof返回陣列長度,指標返回本身長度。

陣列名預設是指向第一個指標,&arrayName 是整個陣列型別的指標,地址一樣,但是+1運算,一個跨度是陣列包含的型別,一個是整個陣列的長度。

new 建立在堆或自由儲存區中,其他在棧。 short (*p)[20]   型別為整個陣列的指標,  short *p[20] 型別short的指標陣列。

三種管理資料記憶體方式:自動儲存、靜態儲存、動態儲存、執行緒儲存(c++11)

自動儲存:函式裡定義的常規變數,函式結束時,消除。  放在棧上

靜態儲存:整個程式執行期間都存在。函式外定義或者使用static 可以實現該儲存

動態儲存:new建立 delete 刪除  生命週期不受函式控制

c++11提供了auto關鍵字,避免複雜的指標建立 如**p = x    直接auto p=x

模板類vector  內部使用了new和delete進行管理,但是是自動的。  vector<int> xx (n)

模板類array(c++11)  儲存在棧上,申明格式array<int,n> ad   n不能是變數  

陣列必須逐個賦值,array可以整體賦值給另一個array。vector和array  物件有at方法 用來檢查是否越界 xx.at(1),會產生更大的消耗。

指標形參不修改值最好加上const,防止修改值。const無法對指向指標的指標使用。因為會指向指標會修改資料。const修飾的指標可以改變指向,如果使用不能改變指向的指標 需要申明int * const finger = &xxx。可以雙重申明  const int * const finger,這樣不能改變指向的值,也不能改變指向的地址。

模板類array<int,9> 和 結構 預設傳遞值,陣列預設傳遞地址。

auto 只能用於單值初始化,不能用於列表初始化、

虛擬函式內部運用了函式指標

int & xxx=xxx  引用必須初始化賦值,且繫結後不可更改繫結的地址。

函式引數 指標和引用的區別,指標是地址傳遞,引用是傳遞值的別名。
左值:常規變數和const變數,引用引數的函式,傳入的應該是左值。

函式引數為引用型別且型別不一致需要轉換時,傳const是可以的,因為const目的是不改變值。傳型別不符的是不可以的,因為生成的臨時變數,改變值是臨時變數無法改變引用的值,所以禁止了。

一般模板

template<typename T> 

void Swap(T &,T &)

的匹配優先順序小於顯示具體化的模板版本

template <> void Swap<job>(job &,job &)

隱式例項化 就是一般的模板,遇到型別的時候會實列化模板(也就是函式)

顯示具體化申明template <> void Swap<int>(int &,int &) (swap後面的<>可以不加) 命令編譯器直接建立特定的例項

顯示實列化申明template void Swap<int>(int,int)(區別在於template後面沒有<>)    不用模板生成函式定義,使用專門為int型別顯示定義的函式

decltype((xx))  有括號代表的是計算左值的型別,左值型別是引用的型別  如double &

template<class T1,class T2>

auto gt(T1 x,T2 y) -> decltype(x+y){...  return x+y;}  返回型別auto 可實現decltype在引數聲明後面,處於x,y作用域。

包含標頭檔案用 "xxx.h"  而不是<xxx.h>,如果用尖括號,編譯器會在主機檔案系統中的標準標頭檔案中查詢,雙引號會首先在專案目錄中查詢,然後再去系統中查詢。

extern 宣告變數,不分配記憶體。通常是引用外部的靜態外部連結變數。(靜態變數分為靜態無連線,靜態外部連結,靜態內部連結)

函式外宣告初始化的變數時是外部連結,但是宣告的const變數時是內部連結。可在const前面加上extern變成外部連結

函式內使用::x  代表使用x的全域性變數版本。

如果結構申明時為const,想要改變結構內部的變數,則內部變數申明前面加上mutable

函式原型和定義中,加上static,連結性為內部,預設為外部。

定位new運算子,分配變數到指定的地址中   int * p1=new (buffer) int[10]   int陣列分配到buffer地址

預設情況下,將一個物件賦值給同類型的另一個物件時,c++會將原物件的每個資料成員的內容複製到目標物件的相應資料成員中去。

stock= Stock("xx","xx")  stock之前已經定義過,這次操作會產生一個臨時物件,並將值賦值到stock中去,然後呼叫解構函式,刪除該臨時物件。

只要方法不修改呼叫物件,都應該在方法後加上const  如:void show() const;  void stock::show() const

接受一個引數的建構函式允許使用賦值對其初始化

enum xxx{x1} 列舉成員x1可以隱式的轉為int : x1   enum class xxx{x1} 成員需要顯式的轉換: int(xxx::x1)

explicit 方法申明前加上這個  防止隱式轉換

返回未經過new的物件時,如果返回的時指標,物件會被釋放,返回的空指標。如果返回的時物件,返回的時候會建立該物件的副本返回,原物件釋放。

友元函式是指類內部的函式,非成員函式(沒有x::字首)還可以訪問類內部的成員(沒有訪問內部成員的,不必是友元),如cout<<xxx就是過載了<<的友元函式。

返回物件的引用&  返回指標*

顯示轉化,在類內部加上operator int() const   就可以  int(typename)  注意避免二義性

建構函式分為預設建構函式。複製建構函式(xxx(const xxx &))按值傳遞的時候觸發,相當於把每個成員賦值給新的成員,這在解構函式釋放資源的時候,如果呼叫了複製,會出異常,解決方法時過載複製建構函式,然後進行deep copy,如字串進行std::strcpy,這樣複製的物件釋放不會影響原來的物件。賦值運算子過載(=),初始化的時候xxx d = ff,呼叫的時複製建構函式,d=ff呼叫的是賦值過載,class_name & class_name::operator=(const class_name &),預設和複製建構函式一樣,複製成員。

空指標建議用nullptr  而非0(0是相容以前的版本)

使用了virturl,使用引用或指標指向的物件的真實型別選擇呼叫,如沒有,根據引用或指標的型別呼叫。

虛擬函式的基類和派生類 都有虛擬函式表的陣列,記錄了虛擬函式的地址。每個函式一個地址組成的陣列,派生類中也有基類的虛擬函式地址,如果派生類沒有定義的話。稱為動態聯編,解構函式也應當申明虛擬函式,以便讓派生類的資源得到釋放。虛擬函式不支援過載(同函式名,不同的引數,派生類根據函式名覆蓋,除非定義所有的基類的同名函式,這樣就可以呼叫基類的虛方法),所以派生類的方法應與基類虛方法完全相同,返回型別如果是基類,可以修改為派生類(返回型別協變)

純虛擬函式在函式定義後面加上 =0,則該類不能建立,只能被繼承。然後再定義不同的繼承類和他們的實現。

初始化列表包含多個專案時,按照屬性宣告的順序進行初始化,而不是初始化函式後面的初始化列表的順序。

類後面繼承關鍵字為private 是私有繼承,基類一切在子類中可使用,但是無法對外暴露。protect同理

 (部落格園丟失了一大半,未儲存,心痛,彈個手機設定框,把我的都弄沒了)友元、異常、string類、stl相關的(vector常用,其他的看場景)容器類:deque,list,queue,priority_queue,stack,vector,map,multimap,set,multiset,bitset,c++11新增forward_list(不支援隨機訪問,遍歷)unordered_map,unordered_set,unordered_multiset,不將bitset視為容器,剩下的等到讀第二遍再說

 stl有四種關聯容器set,multiset,map,multimap。set值型別和鍵相同,鍵唯一,multiset 鍵不唯一,內部pair型別。map  值與鍵型別不同,鍵唯一,multimap 鍵不唯一。

set<string> A,第二個引數可選,是對鍵用來排序比較的函式或物件,預設為less,set<string,less<string>> A;        string s1[n]={....}  set<string> A(s1,s1+n),與其他容器相似,set內部也有將一個迭代器區間作為引數的建構函式。

並集的方法 set_union(a.begin(),a.end(),b.begin(),b.end(),ostream_iterator<string,char> out(cout, " "));  也可以插入到某個集合去,set_union(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<string>>(c,c.begin))); 

set_intersection()和set_difference()查詢交集和獲得兩個集合的差,與set_union介面相同。

multimap count接受key引數放回值的個數。equal_range()key引數,返回迭代器,多個值。multimap<int,string> codes;  codes.insert(pair<int,string>(415,"xxx"))  

函式物件,也叫函式符,可以以函式方式和()結合。定義了operator()()的類。

for_each可以將指定的函式用於區間內的每個成員,for_each(a.begin(),a.end(),ShowReview),第三個引數可以是常規引數,也可以是函式符。但不能是函式指標,因為函式指標指定了引數型別,而容器可以包含任意型別。stl使用了模板來解決這個問題。for_each原型看上去是這樣template<class InputIterator,class Funcation>     Function for_each(InputIterator first,InputIterator last,Funcation f)     ShowReview()原型:void ShowReview(const Review &) 對於不同的函式呼叫,Function引數可以表示具有過載的()運算子的類型別

 slice類物件可作用陣列,三個引數代表索引,索引數和跨距。如val[slice(1,4,3)]=10   將val的1,4,7,10   元素設定為10

 

緩衝區的存在是為了匹配不同速率的傳輸。streambuf為快取區的管理提供了方法,ios_base類表示流的一般特徵,是否可讀取,是文字還是二進位制流。ios類基於ios_base,其中包括了一個指向streambuf物件的指標成員。 ostream是從ios類派生而來,提供了輸出方法。istream也是一樣,提供了輸入方法。iostream是基於之前兩個類,提供了輸入輸出。