作者文章閱讀次數 4295

2021-04-13 21:26:48 字數 3015 閱讀 4495

大學的時候學校開了c++的課程,我考的還不錯。畢業後就一直搞軟體開發,大概一年前開始用vc做專案。最近靜下心來看了c++的經典著作《effective c++ 》,才發現自己的c++水平其實真的很一般!書中提到的有些東西,我竟然從來沒有注意過!還有些竟然是我第一次聽說!

下面以例項說明(我用我寫的更小的例子代替了書中的例子,書中原文我用紅色標示)。

1.關於類成員的初始化順序問題

條款13的標題是:initialization list中的members初始化次序應該和其在class內的宣告次序相同。

我不知道大家在用c++開發的時候有沒有注意過這個問題,反正我是從來沒有往這方面想過!

下面來看例子:

class cmyintarray

;private:

std::vector

data;

size_t size;

int lbound, hbound;

}; cmyintarray::cmyintarray(int lowbound, int highbound)

: size(highbound - lowbound + 1)

, lbound(lowbound)

, hbound(highbound)

, data(size)

如果沒有看過這本書,沒有任何提示,我想很多搞c++開發的人看不出這簡單幾行**有什麼問題(當然,編譯肯定是不會有問題的)。

可是,如果程式中有類似於下面的**,問題就會在程式執行的時候爆發出來:

cmyintarray otest(5, 13);

cout << otest.getarraysize() << endl;

而且你就算在debug狀態下進行跟蹤也很難發現問題的根源所在!

問題處在什麼地方呢?就在於成員變數的宣告次序上!上面變數宣告的次序改為:

size_t size;int lbound, hbound;

std::vector

問題就可以迎刃而解!

驚奇嗎?為什麼會這樣?書中給出了答案:class members係以它們在class內的宣告次序來初始化;和它們在member initialization list中出現的次序完全無關。

上面**的錯誤根源是:data在初始化的時候size還沒有定義!也就是說要初始化乙個沒有定義大小的vector,當然會出錯。

2.關於「切割問題」

下面是書中的一段話(條款22中):

當乙個derived class object被交出去當作乙個base class object時,它原本所以「成為乙個derived class object」的所有特徵,都會被切除(slicing)掉,只留下內部乙個base class object。

下面是我寫的小例子:

class cbase

; };class cderived : public cbase

; };

下面是兩個函式:

void test1(cbase test)

void test2(const cbase& test)

用下面的**分別呼叫函式test1和test2:

cderived otest;

test1(otest);

test2(otest);

問題是:呼叫函式test1和函式test2分別輸出什麼?

正確答案是:

output from cbase!

output from cderived!

驚奇嗎?一點兒也不驚奇!書中已經給出了為什麼會這樣:以by reference的方式傳遞引數,有另乙個優點:可避免所謂的「切割(slicing)問題」。

3.關於非虛函式的靜態繫結和虛函式的動態繫結

下面是例子:

class cbase

; };class cderived : public cbase

; };

現在有下面的**呼叫:

cderived d;

cbase *pb = &d;

pb->test();

cderived *pd = &d;

pd->test();

輸出是:

output from cderived!

output from cderived!

output from cbase!

output from cderived!

這時,有些人就會奇怪了,pb和pd指向的都是d,為什麼會這樣輸出呢?

答案就是:非虛函式是靜態繫結的,虛函式是動態繫結的。

4.關於預設值的靜態繫結

還是看例子:

class cbase

;class cderived : public cbase

; };

下面是呼叫**:

cbase *p = new cderived;

p->test();

我們的本意是想輸出1,可是結果卻是輸出0!

不用驚奇,書中給出了答案:虛函式系動態繫結(dynamically bound),而預設引數值卻是靜態繫結(statically bound)。

寫在最後:其實vc和bcb之類的只能是c++的開發工具,而基礎還是c++。就算你的vc和bcb用得再熟練,也是僅僅是對其提供的類庫而已,而沒有真正領會c++的精髓。這些是我看了這本書後的感想。現在覺得靜下心來看了這本書,真是受益匪淺呀。希望這篇文章能給讀者一點啟發。我的下乙個目標就是讀c++之父bjarne stroustrup的那本經典著作《the c++ programming language》。如果我有什麼收穫,也會在這裡給大家分享。

本文**

文章 《SOA治理》作者訪談

就新發布的 soa治理 實現並保持業務和it的機動性 一書,infoq採訪了它的作者clive gee,william a.brown,robert g.laird和tilak mitra等人,採訪的內容包含了重用在soa中的地位 用於soa治理的工具以及業務和it對齊等。相關的問題有 u0026 ...

LMCF文章閱讀

這篇文章的作者在知乎上有比較詳細的中文介紹 利用迴圈移位樣本的特徵圖 circulant feature maps 與乙個向量的內積,作為是目標的可能性 目標函式的約束條件 使得目標中心處的patch是目標的可能性大於 w,h 處是目標的可能性超過乙個距離。意為large margin!w和z其中乙...

SDN文章閱讀

閱讀文章 軟體定義網路 sdn 研究進展 並根據所閱讀的文章,書寫一篇部落格,回答以下問題 至少3個 簡單的說,就是因為傳統網路其網路裝置有過度複雜的協議,難以優化和部署新協議,同時,網際網路流量的快速增長,使用者對流量的需求不斷擴大,各種新型服務不斷出現,增加了網路運維成本.所以需要一種新型的網路...