C Primer Plus第6版18個重點筆記

2021-09-06 19:53:11 字數 4751 閱讀 5189

下面是我看《c++ primer plus》第6版這本書後所做的筆記,作為備忘錄便於以後複習。

筆記部分

c++的const比c語言#define更好的原因?

首先,它能夠明確指定型別,有型別檢查功能。

其次,可以使用c++的作用域規則將定義限制在特定的函式或檔案中。

第三,可以將const用於更複雜的型別,比如陣列和結構。

c語言中也有const,其與c++中const的區別是:一是作用域規則不同;另乙個是,在c++中可以用const值來宣告陣列長度。

不能簡單地將整數賦給指標,如下所示:

int *ptr;

ptr = 0xb8000000; //

type mismatch

int *ptr;

ptr = (int *) 0xb8000000; //

type now match

這樣,賦值語句的兩邊都是整數的位址,因此這樣賦值有效。

注意,pt是int值的位址並不意味著pt本身的型別是int。例如,在有些平台中,int型別是個2位元組值,而位址是個4位元組值。

為什麼說字首++/--比字尾++/--的效率高?

對於內建型別和當代的編譯器而言,這看似不是什麼問題。然而,c++允許您針對類定義這些運算子,在這種情況下,使用者這樣定義字首函式:將值加1,然後返回結果;但字尾版本首先複製乙個副本,將其加1,然後將複製的副本返回。因此,對於類而言,字首版本的效率比字尾版本高。

總之,對於內建型別,採用哪種格式不會有差別,但對於使用者定義的型別,如果有使用者定義的遞增和遞減運算子,則字首格式的效率更高。

逗號運算子

到目前為止,逗號運算子最常見的用途是將兩個或更多的表示式放到乙個for迴圈表示式中。逗號運算子的特性有下面幾個:

有用的字元函式庫cctype

從c語言繼承而來,老式格式是ctype.h,常用的有:

快排中中值的選取:

將元素每5個一組,分別取中值。在n/5個中值裡面找到中值,作為partition的pivot。

為什麼*不每3個一組?保證pivot左邊右邊至少3n/10個元素,這樣最差o(n)。

c++儲存方案:c++三種,c++11四種

這些方案的區別就在於資料保留在記憶體中的時間。

自動儲存持續性:在函式定義中宣告的變數(包括函式引數)的儲存持續性為自動的。它們在程式開始執行其所屬的函式或**塊時被建立,在執行完函式或**塊時,它們使用的記憶體被釋放。c++有兩種儲存持續性為自動的變數。

靜態儲存持續性:在函式定義外定義的變數和使用關鍵字static定義的變數的儲存持續性都為靜態。它們在程式整個執行過程中都存在。c++有3種儲存持續性為靜態的變數。

執行緒儲存持續性(c++11):當前,多核處理器很常見,這些cpu可同時處理多個執行任務。這讓程式能夠將計算放在可並行處理的不同執行緒中。如果變數是使用關鍵字thread_local宣告的,則其生命週期與所屬的執行緒一樣長。本書不**並行程式設計。

動態儲存持續性:用new運算子分配的記憶體將一直存在,直到使用delete運算子將其釋放或程式結束為止。這種記憶體的儲存持續性為動態,有時被稱為自由儲存(free store)或堆(heap)。

自己寫string類注意事項:

何時呼叫拷貝(複製)建構函式:

stringbad ditto (motto);   

stringbad metoo =motto;

stringbad also =stringbad(motto);

stringbad * pstringbad = new stringbad (motto);

以上4中方式都將呼叫:stringbad(const stringbad &)

何時呼叫賦值運算子:

與複製建構函式相似,賦值運算子的隱式實現也對成員進行逐個複製。如果成員本身就是類物件,則程式將使用為這個類定義的賦值運算子來複製該成員,但靜態資料成員不受影響。

賦值運算子和拷貝建構函式在實現上的區別:

下面的**說明了如何為stringbad類編寫賦值操作符:

stringbad & stringbad::operator=(const stringbad &st)

**首先檢查自我複製,這是通過檢視賦值操作符右邊的位址(&s)是否與接收物件(this)的位址相同來完成的,如果相同,程式將返回*this,然後結束。

如果不同,釋放str指向的記憶體,這是因為稍後將把乙個新字串的位址賦給str。如果不首先使用delete操作符,則上述字串將保留在記憶體中。由於程式程式不再包含指向字串的指標,一次這些記憶體被浪費掉。

接下來的操作與複製建構函式相似,即為新字串分配足夠的記憶體空間,然後複製字串。

賦值操作並不建立新的物件,因此不需要調整靜態資料成員num_strings的值。

過載運算子最好宣告為友元

比如將比較函式作為友元,有助於將string物件與常規的c字串進行比較。例如,假設answer是string物件,則下面的**:

if("love" == answer)

將被轉換為:

if(operator == ("love", answer))

然後,編譯器將使用某個建構函式將**轉換為:

if(operator == (string("love"), answer))

這與原型是相匹配的。

在重寫string類時使用中括號訪問字元時注意:

(1)為什麼過載的返回值是個char &而不是char?

(2)為什麼有兩個過載的版本,另乙個是const版本?

解答(1):

將返回類制宣告為char &,便可以給特定元素陚值。例如,可以編寫這樣的**:

string means ("might");

means [9] = ' r';

第二條語句將被轉換為乙個過載運算子函式呼叫:

means.operator[0] = 'r';

這裡將r陚給方法的返回值,而函式返回的是指向means.str[0]的引用,因此上述**等同於下面的**:

means.str[0] = 'r';

**的最後一行訪問的是私有資料,但由於operator 是類的乙個方法,因此能夠修改陣列的內容。 最終的結果是「might」被改為「right」。

解答(2):

假設有下面的常量物件:

const string answer("futile");

如果只有上述operator定義,則下面的**將出錯:

cout << answer[1]; // compile-time error

原因是answer是常量,而上述方法無法確保不修改資料(實際上,有時該方法的工作就是修改資料, 因此無法確保不修改資料)。

但在過載時,c++將區分常量和非常量函式的特徵標,因此可以提供另乙個僅供const string物件使用 的 operator版本:

// for use with const string objects

const char & string::operator const

有了上述定義後,就可以讀/寫常規string物件了 :而對於const siring物件,則只能讀取其資料。

靜態成員函式在類宣告外定義實現時不能再加static關鍵字,與靜態成員變數一樣。

實現has-a關係的兩種方法:

然而,私有繼承所提供的特性確實比包含多。例如,假設類包含保護成員(可以是資料成員,也可以是成員函式),則這樣的成員在派生類中足可用的,但在繼承層次結構外是不可用的。如果使用組合將這樣的類包含在另乙個類中,則後者將不是派生類,而是位於繼承層次結構之外,因此不能訪問保護成員。但通過繼承得到的將是派生類,因此它能夠訪問保護成員。

另—種需要使用私有繼承的情況是需要重新定義虛函式。派生類可以重新定義虛函式,但包含類不能。使用私有繼承,重新定義的函式將只能在類中使用,而不是公有的。

關於保護繼承

保護繼承是私有繼承的變體,保護繼承在列出基類時使用關鍵字protected;

class student : protected std::string

,

protected std::valarray

使用保護繼承時,基類的公有成員和保護成員都將成為派生類的保護成員,和私有繼承一樣,基類的介面在派生類中也是可用的,但在繼承層次結構之外是不可用的。當從派生類派生出另乙個類的時,私有繼承和保護繼承之間的主要區別便呈現出來了。使用私有繼承時,第三代將不能使用基類的介面,這是因為基類的共有方法在派生類中將變成私有方法;使用保護繼承時,基類的公有方法在第二代中將程式設計呢個受保護的,因此第三代派生類可以使用它們。下表總結了公有、私有和保護繼承。隱式向上轉換意味著無需進行顯式型別轉換,就可以將基類指標或引用指向派生類物件。

智慧型指標相關

請參考:c++智慧型指標簡單剖析,推薦必看。

c++中的容器種類:

關聯容器

C Primer Plus 第6版 總結複習(5)

組織程式 是處理資料的另乙個方面,讓程式按正確的順序執行各個步驟。define指令建立符號常量 const限定符建立不可更改的變數 此 不全 shoe 3.0 while shoe 18.5 小於 while語句 迭代語句,又稱結構化語句 三部分 關鍵字while 圓括號中是待測試的條件 如果測試條...

C Primer Plus(第6版)第四章程式設計練習

1.編寫乙個程式,提示使用者輸入名和姓,然後以 名,姓 的格式列印出來。include include int main 4.編寫乙個程式,提示使用者輸入身高 單位 英吋 和姓名,然後以下面的格式顯示使用者剛輸入的資訊 dabney,you are 6.208 feet tall 使用float型別...

unix網路程式設計第2版 卷1 第6章 同步

6.1概述 在5.12節中,我們看到tcp客戶同時處理兩個輸入 標準輸入和tcp套介面。我們遇到的問題是客戶阻塞於 標準輸入上的 fgets呼叫,而伺服器程序又被殺死。伺服器tcp雖正確地給客戶tcp發了乙個fin,但客戶程序正阻塞於從標準輸入讀入,它直到從套介面讀時才能看到此檔案結束符 可能已經過...