【Accelerated C++】重点回顾(续)
看了劉未鵬推薦過的C++入門經(jīng)典《Accelerated C++》,讀此書的過程中一再感嘆“大師就是大師,他可以很輕松的把東西的本質(zhì)呈現(xiàn)在你面前”,這本書采用了現(xiàn)實中與我們很接近的學生成績信息管理這一例子,層層推進,一步一步引出C++中的知識點,根據(jù)任務(wù)提出解決方案,讓你感受到C++中一些設(shè)計的比要性。
一下是我讀此書時做的筆記,謹用于記憶。
ps:這篇是第二篇,之前的筆記請看這個鏈接【Accelerated C++】重點回顧。
第八章、編寫泛型函數(shù)
? ? C++語言的一個重要特性就是可以使用并創(chuàng)建泛型函數(shù)。
2、而且僅有一個類型以特定的方式支持特定的操作集時,這個類型才是迭代器。
3、實現(xiàn)泛型函數(shù)的語言特性叫做‘模板函數(shù)’(template function)
? ? ? --模板是標準庫的基石。
? ? template <class T>
? ? T median( vector<T> v ){
? ? ? ? ...
? ? }
? ? T為類型參數(shù)。
4、模板實例化
? ? 當我們一個vector<int>對象調(diào)用median函數(shù)時,系統(tǒng)會高效的創(chuàng)建并編譯這個函數(shù)的一個實例,而且在這個函數(shù)中所有T都會用int來取代。
? ? C++標準并沒有說明系統(tǒng)改如何管理模板實例化,所以每個系統(tǒng)都按照它自己的特殊方式來解決實例化。
? ? 模板實例化有兩點需要明確的:
? ? ? ? 1)C++系統(tǒng)遵循的是傳統(tǒng)的編輯-編譯-鏈接模板,實例化往往不是發(fā)生在編譯時期,就是在鏈接時期。直到模板實例化,系統(tǒng)才會檢驗?zāi)0宓拇a是否可用用于指定的類型。
? ? ? ? 2)當前的大多數(shù)系統(tǒng)都要求,為了可用實例化一個模板,模板的定義,而不僅僅是聲明,都必須是系統(tǒng)可以訪問的。這意味著:定義模板的源文件和頭文件都必須是可訪問的。很多系統(tǒng)都希望模板的頭文件可以包含源文件 --->函數(shù)聲明與定義都在.h文件中。
5、標準庫定義了5個迭代器種類:
? ? 1)順序只讀訪問 ? ? -->輸入迭代器 ? ? ? ? ? ? ? ? ? ?只能輸入
? ? 2)順序只寫訪問 ? ? -->輸出迭代器 ? ? ? ? ? ? ? ? ? ?只能輸出
? ? 3)順序讀寫訪問 ? ? -->前向迭代器(所有標準庫都滿足),既能輸入,也能輸出
? ? 4)可逆訪問 ? ? ? ? -->雙向迭代器(容器類都支持) , ? 既能輸入,也能輸出
? ? 5)隨機訪問 ? ? ? ? --高效的隨機訪問任意元素, ? ? ? 既能輸入,也能輸出
6、為什么下界常常是指向最后一個元素的下一個值? ? ? (更簡單,可靠)
? ? 1)如果這個區(qū)間沒有任何元素,那么就沒有能標記末尾的最后一個元素。--如果在開始元素之前的位置標記為空區(qū)間,會降低程序的可靠性。
? ? 2)可以讓我們只需要比較迭代器的相等性和不等性。
? ? ? ? while( begin != end )
? ? ? ? ? ? ++begin;
? ? 3)可以為我們提供一種罪自然的方式來表示'區(qū)間之外'。
7、如果沒有標準庫需要區(qū)分輸入輸出迭代器和前向迭代器的話,為什么還分出這兩個種類呢?
? ? 其中的一個原因是,并不是所有迭代器都與容器相關(guān)聯(lián)。比如:
? ? ? ? 標準庫提供了可以和輸入輸出流綁定的迭代器。用于istream的迭代器滿足輸入迭代器的要求,用于ostream的迭代器滿足輸出迭代器的要求。
? ? ? ? 使用適當?shù)牧鞯?#xff0c;我們可以通過普通的迭代器操作來控制一個istream或者一個ostream。 流迭代器就是一個模板。
8、C++標準庫的一個重要貢獻就是,通過把迭代器用作算法和容器之間的粘合劑,算法可以獲得數(shù)據(jù)結(jié)果的獨立性。此外,算法使用的迭代器都要求支持某些操作,這樣我們就可以根據(jù)這些操作來分解算法,這就意味著,我們可以很容易的把一個容器和能夠在這個容器上使用的算法匹配起來。
第九章、定義新類型
1、C++有種類型:
? ? 內(nèi)置類型和類。
2、許多C++設(shè)計都基于這樣的一種思想:
? ? 允許程序員創(chuàng)建于內(nèi)置類型一樣易用的類型。
3、即便一個程序從來沒有直接的創(chuàng)建人和const對象,它也可能會通過調(diào)用創(chuàng)建大量的const對象的引用。
? ? 如:當我面把一個非const對象傳遞給帶有一個const引用的函數(shù)時,這個函數(shù)就會把這個對象當做是const對象來處理,編譯器也將只允許它調(diào)用這種對象的const成員。
4、何時為成員函數(shù),何時為非成員函數(shù)?
? ? 有一個通用的規(guī)則:如果這個函數(shù)會改變對象的狀態(tài),那么這個函數(shù)就應(yīng)該成為這個對象的成員。
5、struct與class的唯一區(qū)別:
? ? 默認保護的方式不同。默認保護會應(yīng)用于第一個保護標簽之前的所有成員。
? ? struct:第一個保護標簽之前的成員都是public
? ? class: 第一個保護標簽之前的成員都是private
6、訪問器函數(shù)
? ? 因為我們隱藏了數(shù)據(jù)成員,因此我們需要定義一個訪問器函數(shù)來進行訪問。
? ? std::string name() const{ return str; }
? ? 那么函數(shù)是一個const成員函數(shù),它不帶有任何參數(shù),并且返回一個string值,也就是str的一個副本。通過復制str,而不是返回它的一個引用。
? ? 這樣的函數(shù)經(jīng)常被允許簡單地訪問隱藏的數(shù)據(jù),這樣就破壞了我們想要得到的封裝性。
? ??
? ? 只有當訪問器是類的抽象接口的一部分時,才應(yīng)該提供訪問器。
? ? 這里,我們抽象出了一個學生和一個對應(yīng)的最終成績,所以提供一個name函數(shù)是合適的。換句話說,我們并沒有提供其他的成績--midterm、final、或者homework的訪問器。因為這些成績都是時下的基本組成部分,而不是接口的組成部分。
7、當創(chuàng)建標準庫中某個類的一個對象時,標準庫可以保證這個對象開始時會有一個適當?shù)闹怠?br />
8、構(gòu)造函數(shù)?
? ? 是特殊的成員函數(shù),它定義了對象如何初始化。我們沒有辦法顯示調(diào)用一個構(gòu)造函數(shù)。但是創(chuàng)建類的一個對象時就會自動的調(diào)用適當?shù)臉?gòu)造函數(shù)。
? ? 如果沒有定義任何夠做函數(shù),編譯器就會為我們合成一個。
9、默認合成的構(gòu)造函數(shù)的規(guī)則:
? ? 1)如果一個對象的類型是定義了一個或多個構(gòu)造函數(shù)的類的話,那么適當?shù)臉?gòu)造函數(shù)會完全控制這個類的對象的初始化。
? ? 2)如果一個對象的類型是內(nèi)置類型的話,那么值初始化會把它設(shè)置為0,而默認初始化會提供一個不明確的值。
? ? 3)否則,這個對象的類型只能是沒有定義任何構(gòu)造函數(shù)的類。
? ? ? ? 如果是這樣的話,對這個對象進行值初始化或者默認初始化就會對它的每個數(shù)據(jù)成員進行適當?shù)闹党跏蓟蛘吣J初始化。如果這個對象的任何一個數(shù)據(jù)成員的類型也是一個類,而且這個類帶有自己的構(gòu)造函數(shù)的話,初始化過程就會遞歸的進行。
10、我們應(yīng)該確保每個數(shù)據(jù)成員任何時候都有一個有意義的值。
11、默認構(gòu)造函數(shù):
? ? 不帶有任何參數(shù)的構(gòu)造函數(shù)被認為是默認構(gòu)造函數(shù)。
? ? 它的工作是確保對象的數(shù)據(jù)成員被適當?shù)爻跏蓟?br />
12、系統(tǒng)在創(chuàng)建一個新的類對象時,會發(fā)生下面幾個連續(xù)的步驟:
? ? 1)系統(tǒng)會分配內(nèi)存空間,以保存這個對象。
? ? 2)根據(jù)構(gòu)造函數(shù)的初始化列表,初始化這個對象。
? ? 3)執(zhí)行構(gòu)造函數(shù)的函數(shù)體。
13、系統(tǒng)會初始化每個對象的每個數(shù)據(jù)成員。不管夠做函數(shù)初始化列表中是否有這些成員。
? ? 雖然夠做函數(shù)的函數(shù)體隨后可能會改變這些初始值,但是初始化列表會在構(gòu)造函數(shù)的函數(shù)體執(zhí)行前執(zhí)行。
? ? 通常來說,顯示的為一個成員提供一個初始值,要比在構(gòu)造函數(shù)的函數(shù)體中對這個成員進行賦值要好的多。
? ? ? ? 通過這樣的初始化,而不是進行賦值操作,我們可以避免做兩次相同的工作。
14、對于內(nèi)置類型的成員來說,在構(gòu)造函數(shù)中為它們提供一個值顯得尤為重要。
? ? 因為,如果沒有初始化,那么在局部生存空間中聲明的對象就會使用垃圾信息來初始化。
15、成員初始化的順序取決于它們在類中聲明的順序。
? ? 因此,應(yīng)該要避免順序的依賴性--->在構(gòu)造函數(shù)的函數(shù)體中對這些成員賦值,而不是在構(gòu)造函數(shù)初始化列表中初始化它們。
第十章、管理內(nèi)存和底層數(shù)據(jù)結(jié)構(gòu)
1、理解標準庫的關(guān)鍵是:
? ? 使用核心語言的編程工具和技巧,這些方法在其他地方也派的上用場。
2、數(shù)組和指針:
? ? 數(shù)據(jù)也是一種容器。
? ? 指針是一種隨機訪問的迭代器。
3、指針是表示對象的地址的一個值。每個不同的對象都有一個唯一的地址,這個地址表示計算機中保存這個對象的內(nèi)存空間。
? ? 如果x是一個對象,那么&x就是它的地址,
? ? 如果p是一個對象的地址,那么*p就是對象本身。
? ? &x中的&是一個取地址操作符。
? ? *是一個解引用操作符,作用類似于迭代器上的*的作用。
4、程序員們經(jīng)常使用0值來初始化指針,因為
? ? 可以把0轉(zhuǎn)換為指針時可以生成一個值,它可以確保與指向任何對象的指針的值不同。
? ? 而且,常數(shù)0是唯一一個可以轉(zhuǎn)換成指針類型的整數(shù)值。
? ? 從0轉(zhuǎn)換生成的值,常常稱為空指針。
5、指向函數(shù)的指針
? ? 沒有程序可以創(chuàng)建或修改一個函數(shù),只有編譯器可以做這個工作。
? ? 對于函數(shù)來說,程序所能做的,僅僅是調(diào)用它或者取得它的地址。
6、int (*fp)(int);
? ? fp是一個函數(shù)指針,它所指的函數(shù)帶有一個int類型的參數(shù),并且返回int類型的結(jié)果。
? ? int next( int n )
? ? {
? ? ? ? return n+1; ?
? ? }
? ? 可以使用下列任一條,使fp指向next函數(shù):
? ? ? ? fp = &next;
? ? ? ? fp = next;?
? ? 可以完全這樣的操作:
? ? ? ? i = (*fp)(i);?
? ? ? ? i = fp(i);?
7、
8、數(shù)組:
? ? 不能動態(tài)的增長或收縮,編譯時期,必須知道數(shù)組匯總的元素個數(shù)。
? ? 數(shù)組名:就是一個指向數(shù)組中首元素的指針。
9、字符串直接量
? ? 一個字符串直接量實際上是一個const char數(shù)組,它包含的元素個數(shù)比字面上的字符數(shù)多1.--‘\0’
? ? 字符串直接量就是一個指針,指向空字符終止的數(shù)組的首字符。
10、3中內(nèi)存管理
? ? 1)自動內(nèi)存管理
? ? ? ? 系統(tǒng)在運行時為這個局部變量分配所需內(nèi)存,并子退出時釋放。
? ? ? ? int* invalid_pointer()
? ? ? ? {
? ? ? ? ? ? int x;?
? ? ? ? ? ? return &x; ?
? ? ? ? }
? ? ? ? 這個函數(shù)會返回局部變量x的引用,但是,返回時,x所占的內(nèi)存已經(jīng)被釋放。&x創(chuàng)建的指針現(xiàn)在是無效的。
? ? 2)靜態(tài)內(nèi)存管理
? ? ? ??
? ? ? ? int* pointer_to_static()
? ? ? ? {
? ? ? ? ? ? static int x;?
? ? ? ? ? ? return &x;?
? ? ? ? }
? ? ? ??
? ? ? ? 程序?qū)分配一次內(nèi)存,而且只分配一次,并且只要程序在運行,我們就不釋放這個變量的內(nèi)存。
? ? ? ??
? ? ? ? warnning:每次返回一個相同的對象的指針
? ? ? ??
? ? 3)動態(tài)分配內(nèi)存
? ? ? ? 刪除一個零指針沒有什么影響。
? ? ? ? int *p = new int(42);?
? ? ? ? ++*p; ?//*p is now 43
? ? ? ? delete p;?
? ? ? ? int* pointer_to_dynamic()
? ? ? ? {
? ? ? ? ? ? return new int(0);?
? ? ? ? }
? ? ? ? 調(diào)用這個函數(shù)的程序應(yīng)該在適當?shù)臅r候負責釋放這個對象。
第十一章、定義抽象數(shù)據(jù)類型
1、當設(shè)計一個類時,一般都首先指定需要提供的接口。
2、內(nèi)存分配
? ? 使用new T[n] 不僅會分配好內(nèi)存空間,還會調(diào)用T的默認構(gòu)造函數(shù)來初始化每個元素。
? ? 如果我們使用了new T[n],那么我們就對T強加了一個要求:只有當T有一個默認構(gòu)造函數(shù)時,用戶才能創(chuàng)建一個Vec<T>對象。
3、explicit:
? ? 意思是:只有在用戶明確地調(diào)用這個構(gòu)造函數(shù)的地方,編譯器才能使用這個構(gòu)造函數(shù),否則無法使用。
? ? 這個關(guān)鍵字只在帶有一個參數(shù)的構(gòu)造函數(shù)的定義中有意義。
4、通常的,迭代器本身也是類。
5、一般來說,操作符函數(shù)可以是成員函數(shù),也可以是非成員函數(shù)。
? ? 然而,索引操作符是必須為成員函數(shù)的操作之一。
6、索引操作符可以找到底層數(shù)組的對應(yīng)位置,然后返回這個位置的元素的引用。
? ? 返回引用的原因:
? ? ? ? 如果保持在容器中的對象很大的話,應(yīng)該避免對這些對象進行復制,這樣效率才更高。
7、類的作者可以控制對戲那個創(chuàng)建,復制,賦值以及銷毀過程中發(fā)生的一切。如果沒有定義這些操作,編譯器會合成這些定義。--可能會導致莫名其妙的行為。
8、復制構(gòu)造函數(shù)
? ? 無聊是顯示復制,還是隱式復制,都是有一個叫做復制構(gòu)造函數(shù)的特殊構(gòu)造函數(shù)來控制的。
? ? 復制構(gòu)造函數(shù)是一個成員函數(shù)。
? ? Vec(const Vec& v);?
? ? 復制不應(yīng)該改變被復制的對象,所以使用const。
7、如果我們復制指針的值,那么復制的指針和原先的指針就都指向相同的底層數(shù)據(jù)。
? ? warnning:其中一個數(shù)值的改變會引起另一個值的改變,因為它們指向的是同一個數(shù)據(jù)。
? ? 解決方案:當復制一個Vec對象時,需要分配新的空間。
8、賦值操作符不同于復制構(gòu)造函數(shù)的地方是:
? ? 賦值操作符往往需要刪掉左操作符已有的值,然后用新的值,也就是右操作符的值來替換。
? ??
? ? 需要考慮自我賦值情況的處理。
9、Vec<T>::operator=( const Vec& rhs )
? ? {
? ? ? ? ...
? ? ? ? return *this;?
? ? }
? ? 使用*this:
? ? ? ? this關(guān)鍵字只在成員函數(shù)內(nèi)部有效。
? ? 須確保返回時,引用的對象仍存在,因此不能返回局部對象的引用。
10、賦值不是初始化
? ? 理解賦值和初始化之間的區(qū)別是學好C++的關(guān)鍵之一。
? ? 初始化: 復制構(gòu)造函數(shù)
? ? 賦值: ? operator=
? ? 區(qū)別:
? ? ? ? 賦值總會刪除先前的值,而初始化不會這樣。而且,初始化會創(chuàng)建一個新的對象,同時為這個對象提供一個值
? ??
? ? 兩者區(qū)別重要的原因:
? ? ? ? 1)構(gòu)造函數(shù)總是用來控制初始化
? ? ? ? 2)operator=成員函數(shù)總是用來控制賦值操作
? ? 初始化會發(fā)生在:
? ? ? ? 1)變量聲明中
? ? ? ? 2)在函數(shù)如果中,傳遞函數(shù)參數(shù)的時候
? ? ? ? 3)在函數(shù)返回語句中,返回一個值的時候
? ? ? ? 4)在構(gòu)造函數(shù)初始化列表中
? ? 賦值發(fā)生在:
? ? ? ? 在表達式中使用=操作符的時候
? ??
? ? 如:
? ? ? ? string url_ch = "zerocool"; ? ? ? ? //initialization
? ? ? ? string spaces(url_ch.size(), ''); ? //initialization
? ? ? ? string y; ? ? ? ? ? ? ? ? ? ? ? ? ? //initialization
? ? ? ? y = url_ch; ? ? ? ? ? ? ? ? ? ? ? ? //assignment
11、析構(gòu)函數(shù):無人和參數(shù)與返回值,控制類的對象被銷毀時發(fā)生的操作。
12、良好的習慣:為每個類提供一個 默認構(gòu)造函數(shù)(可能是顯式或隱式的提供)
13、如果類的作者沒有定義賦值構(gòu)造函數(shù)、賦值操作符、析構(gòu)函數(shù)---編譯器會生成默認版。
? ? 默認版的函數(shù)會定義為遞歸操作————根據(jù)元素類型的適當規(guī)則、賦值、復制或者銷毀數(shù)據(jù)元素。
? ? warnning:默認析構(gòu)函數(shù)來銷毀一個指針時,并不會釋放指針指向的內(nèi)存空間。
14、三者缺一不可的規(guī)則:
? ? 由于復制構(gòu)造函數(shù)、析構(gòu)函數(shù)以及賦值操作符如此緊密的聯(lián)系在一起,所以它們之間的關(guān)系就形成了一個三者缺一不可的規(guī)則:如果一個類需要一個析構(gòu)函數(shù),那么它也需要其他兩個。
15、使用new:不僅會分配內(nèi)存空間,還會把這些內(nèi)存初始化(即使我們不適用這些元素)
第十二章、使類的對象像數(shù)值一樣工作
本章重點討論如何為類設(shè)計良好的接口。
1、友元
? ? 用來使非成員函數(shù)讀寫成員數(shù)據(jù)。
? ? 可以定義寫成類定義中的任何地方):不管它是跟在private標簽,還是public標簽后,都沒有什么區(qū)別。
? ? 由于友元函數(shù)有特殊的訪問權(quán)限,所以它是類的接口的一部分。因此(最好在類定義的開頭位置,靠近類的公有接口的地方)
2、定義二元操作符
? ? 非成員函數(shù)-->對稱性
? ? 把二元操作符定義為非成員函數(shù)就是一個很好的習慣。這樣做,我們可以保持操作數(shù)之間的對稱性。
? ? 如果一個操作符是一個類的成員,那么這個操作符的左操作數(shù)就不能是自動類型轉(zhuǎn)換的結(jié)果。
3、explicit
? ? 一般來說,如果一個構(gòu)造函數(shù)是用來定義對象的結(jié)構(gòu)的構(gòu)造方式,而不是定義對象內(nèi)容的構(gòu)造方式的話,這個構(gòu)造函數(shù)就會被定義為explicit,、。如果夠做函數(shù)的參數(shù)是對象的一部分的話,這種構(gòu)造函數(shù)就不應(yīng)該定義為explicit。
4、void*類型
? ? 指向void的指針常常被叫做通用指針,這是因為這種指針可以指向任何類型的對象。
? ? 當然,我們不能對這種指針解引用,原因是它指向的對象的類型還是未知的。
? ? 但是我們可以把void*轉(zhuǎn)換為bool類型。
5、類型轉(zhuǎn)換和內(nèi)存管理
? ? 很多C++程序?qū)ο到y(tǒng)的接口都是用C語言或者匯編語言來完成的,這些語言都是使用以空字符終止的字符數(shù)組來保存字符串數(shù)據(jù)的。
6、類型轉(zhuǎn)化是通過非explicit的夠做函數(shù)定義的,并且這種構(gòu)造函數(shù)只帶有一個單獨的參數(shù):類型轉(zhuǎn)換也可以通過類型轉(zhuǎn)換操作符來定義,形式為operator type-name()。
第十三、使用繼承和動態(tài)綁定
1、繼承是oop的基石。
2、系統(tǒng)是如何創(chuàng)建派生類的對象,
? ? 系統(tǒng)首先會為這個對象分配空間。接下來,它會執(zhí)行適當類型的構(gòu)造函數(shù)來初始化這個對象。如果這個對象是派生類的對象,就需要給構(gòu)造過程再加一步,那就是構(gòu)造對象的基類部分。派生類的對象是按照下面的方式來構(gòu)造的:
? ? 1、為整個對象分配空間(包括基類成員和派生類成員)
? ? 2、調(diào)用基類的構(gòu)造函數(shù)來初始化對象中的基類部分
? ? 3、使用構(gòu)造函數(shù)初始化列表直接初始化派生類的成員
? ? 4、如果派生類的構(gòu)造函數(shù)的函數(shù)體中有語句,就執(zhí)行這些語句
3、多態(tài)和虛函數(shù)
? ? 關(guān)鍵字virtual只能用在類定義中。
? ? ? ? 如果這個函數(shù)是在聲明之外單獨定義的話,我們就不需要在定義中重復關(guān)鍵字virtual了。
4、動態(tài)綁定
? ? 虛函數(shù)的運行時選取只與什么時候通過引用或者指針來調(diào)用這個函數(shù)有關(guān)。
? ? 如果通過一個對象(而不是通過對象的引用或者指針)來調(diào)用一個虛函數(shù),當然可以在編譯時知道這個對象的準確類型。一個對象的類型是確定的:它就是它定義時的類型,不會再運行時改變。
? ? 相反,基類的引用或者指針可以引用或指向基類的對象,也可以引用或指向這個基類的派生類的對象,也就是說,引用和指針的類型以及引用和指針綁定的對象的類型,在運行時可能會改變。
5、靜態(tài)綁定:在編譯時綁定
6、動態(tài)綁定和靜態(tài)綁定的區(qū)別是理解C++如何支持OOP的關(guān)鍵。
? ? 如果我們用一個對象來調(diào)用一個虛函數(shù),這個調(diào)用就是靜態(tài)綁定,因為除了編譯時期,對象的類型不可能在執(zhí)行的過程中發(fā)生變化。
? ? 相反,如果我們通過一個指針或者引用來調(diào)用一個虛函數(shù),這個函數(shù)就是動態(tài)綁定,也就是說,是在運行時綁定的。在運行時,使用哪個版本的虛函數(shù),取決于這個引用和指針綁定的對象的類型。
7、我們可以在需要指向基類的指針或引用的地方使用派生類類型,這個例子就是OOP的核心概念————多態(tài)。
? ? 它的意思是,一個類型可以代表多種類型。
? ? C++是通過虛函數(shù)的動態(tài)綁定特性來支持多態(tài)的。
8、虛析構(gòu)函數(shù)
? ? 如果一個指向基類的指針被用來刪除派生類的對象時,基類就需要一個虛析構(gòu)函數(shù)。如果這個類沒有別的理由需要一個析構(gòu)函數(shù)的話,這個虛析構(gòu)函數(shù)就必須被定義,而且函數(shù)體可以為空。
? ? 虛析構(gòu)函數(shù)也可以繼承。
9、派生類沒有必要中定義虛函數(shù)。
? ? 如果一個類沒有重定義虛函數(shù),它就會繼承這個函數(shù)在繼承層次中離當前最近的定義。
? ? 然而,首先出現(xiàn)在這個類中的虛函數(shù)必須被定義。
10、覆蓋
? ? 如果派生類的函數(shù)與基類一樣,就可以覆蓋基類的函數(shù)。
11、友元不能被繼承,也不能傳遞。
from:?http://blog.csdn.net/cyh_24/article/details/8276138
總結(jié)
以上是生活随笔為你收集整理的【Accelerated C++】重点回顾(续)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于C# this 指针
- 下一篇: 深度学习(七)caffe源码c++学习笔