Effective C++ -- 零散知识点整理
Effective C++ --1讓自己習慣C++
Effective C++ --2構造/析構/賦值運算
Effective C++ --3資源管理
Effective C++ --4設計與聲明
Effective C++ --5實現
Effective C++ -- 6繼承與面向對象設計
EffectiveC++ --7模板與泛型編程
Effective C++ --8 定制new和delete && 9雜談討論
?
下面整理的書中遇到的零碎知識點:
?
1、符號表
在條款02中提到,參考http://bbs。csdn。net/topics/330129162
英語為symbol?table,?翻譯成"符號表"應該好理解一些,針對計算機語言,在不同的地方,它的用處也不一樣。有詞法分析時分詞用的符號表。用來把所有用到的標識符區分出來。也有做語法分析時用的語法元素的符號表。編譯成目標文件時,也會產生用于內/外部符號定位/鏈接用的符號表。生成可執行文件時也有類似的符號表。不論在什么地方,符號表的基本都可以看成一個名稱索引表,為了方便數據歸類查找用的。
?#define不會講宏放入記號表,這是為何?
symbol?table是動態的。
比如你寫int?a?=?10,那分詞后會得到?int,?a,?=,?10,?;?這五個符號。這時,分詞用的符號表里就只有這幾個符號及與之對應的信息(比如類型,行號,偏移,文件之類的)。在做語法分析的時候,會直接使用分詞的結果。一般就是分詞用的符號表中的編號。當需要更多的符號信息的時候,就會從分詞符號表時查。
而像宏之類的東西,在編譯之前,會進行預處理。它所用的符號在預處理時就處理過了,所以在具體的編譯時,是沒有這些信息的。
實際上,預處理本身也是一次"編譯"的過程。在預處理的過程中也會有它自己的"符號表"。
2、the enum hack
在條款02中提到,當編譯器不允許static整數型class常量完成in class初值設定時使用的策略,理論基礎是“一個屬于枚舉類型的數值可權充ints被使用”。
classd GamePlayer{private:enum{ NumTurns = 5 };intscores[NumTurns];};3、mutable
在條款03中提到。
mutable的中文意思是:“可變的、易變的”與constant(即C++中 const)是反義詞。C++中的mutable是為了突破const限制而設置的,被mutable修飾的變量將永遠處于可變狀態,即使是位于const修飾的函數中。mutable又是一個奇怪的修飾符(specifier),它只能夠用于一個類的非靜態數據成員。
4、常量性轉除
在條款03中提到,這里利用此技術來實現由non-const成員函數轉換為調用const函數來避免代碼重復。用到了兩個轉型,一個轉型用static_cast來把non-const對象轉型為const對象,調用const成員函數,第二個把const成員函數返回值const類型轉換為non-const類型。
const char& operator[](std::size_tposition) const{ //const成員函數returntext[position];}char& operator[](std::size_tposition){ //non-const成員函數returnconst_cast<char&>( //將返回值的const移出static_cast<constTextBlock&>(*this) //為*this加上const[position] //調用const成員函數);}5、堆和棧
一般動態分配空間在堆,局部變量在棧。
堆:操作系統有一個記錄空閑內存地址的鏈表,當系統收到程序的申請時,會遍歷該鏈表,尋找第一個空間大于所申請空間的堆結點,然后將該結點從空閑結點鏈表中刪除,并將該結點的空間分配給程序,另外,對于大多數系統,會在這塊內存空間中的首地址處記錄本次分配的大小,這樣代碼 中的delete語句才能正確的釋放本內存空間。我們常說的內存泄露,最常見的就是堆泄露(還有資源泄露),它是指程序在運行中出現泄露,如果程序被關閉掉的話,操作系統會幫助釋放泄露的內存。
棧:在函數調用時第一個進棧的主函數中的下一條指令(函數調用語句的下一條可執行語句)的地址然后是函數 的各個參數,在大多數的C編譯器中,參數是由右往左入棧,然后是函數中的局部變量。
6、編譯單元
產出單一目標文件的源碼。當一個c或cpp文件在編譯時,預處理器首先遞歸包含頭文件,形成一個含有所有必要信息的單個源文件,這個源文件就是一個編譯單元。這個編譯單元會被編譯成為一個與cpp文件名同名的目標文件(.o或是.obj)。連接程序把不同編譯單元中產生的符號聯系起來,構成一個可執行程序。
7、vptr(virtual table pointer)
在條款07中提到。欲實現virtual函數,對象必須攜帶某些信息,主要用來在運行時決定哪一個virtual函數該被調用。Vptr指向一個由函數指針構成的數組,稱為vtbl(virtual table)。每一個帶有virtual函數的類都有一個相應的vtbl。當對象調用某個virtual函數時,實際被調用的函數取決于該對象的vptr所指的那個vtbl—編譯器在其中尋找適當的函數指針。
8、TR1
在條款13中提到,在條款54中仔細介紹。
C++ TechnicalReport 1 (TR1)是ISO/IEC TR 19768, C++ Library Extensions(函式庫擴充)的一般名稱。TR1是一份文件,內容提出了對C++標準函式庫的追加項目。這些追加項目包括了正則表達式、智能指針、哈希表、隨機數生成器等。TR1自己并非標準,他是一份草稿文件。然而他所提出的項目很有可能成為下次的官方標準。這份文件的目標在于「為擴充的C++標準函式庫建立更為廣泛的現成實作品」。
C++ tr1是針對C++標準庫的第一次擴展。即將到來的下一個版本的C++標準c++0x會包括它,以及一些語言本身的擴充。tr1包括大家期待已久的smart pointer,正則表達式以及其他一些支持范型編程的東東。草案階段,新增的類和模板的名字空間是std::tr1。
9、80-20經驗法則
平均而言一個程序往往將80%的執行時間花費在20%的代碼上。
這一法則提醒我們,要找出這可以有效增加程序整體效率的20%代碼,然后將它inline或竭盡所能地將它瘦身。
10、“mixin”風格的基類
在條款49中提到。
mixin風格的bases class,用以支持class專屬的set_new_handler。如何針對某個類別計數?通常的做法是:針對該類別設計一組static成員和函數。使用“mixin”風格的基類,可以解決多個類需要多個static成員和函數的問題。此類專為管理類型信息,或者說專為管理static而存在,建立一個同一的包含static的基類,需要的類繼承此類。
“mixin”風格之基類應具有如下特征:
(1)是個模板類
(2)模板參數不被使用(此參數只為生成相應類別之static)
(3)只有static成員和函數
11、“怪異的循環模板模式” (curiously recurring template pattern,CRTP)
在條款49中提到。
意圖:使用派生類作為模板參數特化基類。CRTP不是多態,多態是動態綁定,CRTP是靜態編譯期綁定。如果想在編譯期確定通過基類來得到派生類的行為,CRTP便是一種獨佳選擇,它是通過派生類覆蓋基類成員函數來實現靜態綁定的。
示例代碼:
class derived :public base<derived>{// attributes and behaviors}template <classDerived>struct base{void interface(){// 轉換為子類指針,編譯期將綁定至子類方法static_cast<Derived*>(this)->implementation();}static void static_interface(){// 編譯期將綁定至子類方法Derived::static_implementation();}// 下面兩個方法,默認實現可以存在,或者應該被繼承子類的相同方法覆蓋void implementation();static void static_implementation();};// The Curiously Recurring Template Pattern(CRTP)struct derived_1 : base<derived_1>{// 這里子類不實現,將使用父類的默認實現//void implementation();// 此方法將覆蓋父類的方法static void static_implementation();};struct derived_2 : base<derived_2>{// 此方法將覆蓋父類的方法void implementation();// 這里子類不實現,將使用父類的默認實現//static void static_implementation();};英文鏈接:
http://en.wikibooks.org/wiki/More_C++_Idioms/Curiously_Recurring_Template_Pattern
12、派生類中定義基類的虛函數需要注意的事項
在條款53中介紹了一個派生類定義基類中虛函數少了const引發的問題。
如果我們決定改寫基類所提供的虛擬函數,那么派生類所提供的新定義,其函數型別必須完全符合基類所聲明的函數原型,包括:參數列、返回型別、常量性(const-ness)。當派生類中參數列和返回類型有一個不一樣時編譯器會出錯,當常量性改變時,例如條款中將平派生類中少了const時,會重新定義函數,此時會造成當調用const子類時,只會調用基類的函數,而不會調用子類的。
有一點需要注意:
“返回型別必須完全吻合” 這一規則有個例外:當基類的虛擬函數返回某個基類形式(通常是pointer或reference)時:派生類中的同名函數便可以返回該基類所派生出來的型別,例如:
class Base{ public:virtual Base * clone() const; };class Derived: Base { public:virtual Derived * clone() const; };
可以參考http://www.cnblogs.com/ziyoudefeng/archive/2012/03/20/2407659.html
總結
以上是生活随笔為你收集整理的Effective C++ -- 零散知识点整理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Effective C++ --8 定制
- 下一篇: 《深度探索C++对象模型》--1 关于对