高質(zhì)量C++編程指南-第三版修訂(匯總).doc_第1頁
高質(zhì)量C++編程指南-第三版修訂(匯總).doc_第2頁
高質(zhì)量C++編程指南-第三版修訂(匯總).doc_第3頁
高質(zhì)量C++編程指南-第三版修訂(匯總).doc_第4頁
高質(zhì)量C++編程指南-第三版修訂(匯總).doc_第5頁
已閱讀5頁,還剩15頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

高質(zhì)量程序設計指南C+/C第三版第一刷中已經(jīng)完成的修訂:1 Page 7:倒數(shù)第13行,“啰里啰唆”印刷有點兒問題;2 Page 15:表1-2有些許印刷問題;3 Page 27:第2.1節(jié)的內(nèi)容除了圖2-1外,其他文字全部用下列文字替換(紅色部分是修改過的):1822年,英國人Charles Babbage設計了差分機。該差分機利用卡片輸入程序和數(shù)據(jù),類似于百年后的電子計算機。1834年,Babbage 設計了一臺分析機,在穿孔卡片(只讀存儲器)中存儲程序和數(shù)據(jù),基本實現(xiàn)了控制中心(類似于今天的CPU)和存儲程序的設想。而且程序可以根據(jù)條件進行跳轉,這有些類似于今天的程序控制。1848年,英國數(shù)學家George Boole創(chuàng)立了二進制代數(shù)學,約提前一個世紀為現(xiàn)代二進制計算機鋪平了道路。此后,計算機的研制大約沉寂了40年,自然也沒有什么人來設計程序。1890年,美國進行人口普查。由于1880年的普查用了7年的時間進行統(tǒng)計分析,這意味著1890年的統(tǒng)計分析可能會超過10年。人口普查部門希望能有一臺機器,幫助他們提高統(tǒng)計分析的效率。Herman Hollerith借鑒了Babbage的設計,用穿孔卡片存儲數(shù)據(jù)和程序,并制造了處理機器。結果該機器僅僅用了6周就得出了人口普查的統(tǒng)計分析結果。Herman Hollerith因此大發(fā)橫財,他的公司后來發(fā)展成了IBM公司,真乃時勢造英雄。1896年,Herman Hollerith創(chuàng)辦了IBM公司的前身,開始大量制造穿孔卡片處理機。當真正意義上的電子計算機出現(xiàn)時,穿孔卡片自然地成為最早的程序載體。1906年,美國的Lee De Forest發(fā)明了電子管。在這之前的計算機都基于機械運行方式,而在這之后計算機開始進入電子時代。1924年2月,IBM公司成立了。從那時起直到今天,IBM公司始終在計算機工業(yè)界占據(jù)重要地位。1937年,英國劍橋大學的Alan M. Turing出版了他的論文。沒錯,就是那個著名的圖靈,他在論文中提出了“圖靈機”數(shù)學模型?,F(xiàn)在幾乎所有的編程語言都建立在圖靈機模型之上。1937年,貝爾實驗室的George Stibitz首先用繼電器來表示二進制。如果你是那個時代的先知,也許可以預見到今天的編碼方式。1939年1月1日,加利福尼亞的David Hewlet和William Packard 在他們的車庫里造出了Hewlett-Packard計算機。機器的名字是兩人用投硬幣的方式?jīng)Q定的。這兩個人后來成立了著名的HP公司。世界上第一臺真正意義上的電子數(shù)字計算機實際上是在19351939年間由美國衣阿華州立大學物理系副教授約翰文森特阿塔那索夫(John Vincent Atanasoff)和其合作者克利福特貝瑞(Clifford Berry,當時還是物理系的研究生)研制成功的,用了300個電子管,取名為ABC(Atanasoff-Berry Computer)。不過這臺機器還只是個樣機,并沒有完全實現(xiàn)阿塔那索夫的構想。1942年,太平洋戰(zhàn)爭爆發(fā),阿塔那索夫應征入伍,ABC的研制工作也被迫中斷。但是ABC計算機的邏輯結構和電子電路的新穎設計思想?yún)s為后來電子計算機的研制工作提供了極大的啟發(fā)。所以,阿塔那索夫應該是公認的“電子數(shù)字計算機之父”。1943年,從這一年開始到1959年相繼出現(xiàn)了大量使用電子真空管的計算機,包括ENIAC(Electronic Numerical Integrator and Computer)(它曾一直被人們誤認為是世界上第一臺真正意義上的電子計算機)。ENIAC于1943年開始制造,完成于1946年2月,它的設計思想基本來源于ABC,只是采用了更多的電子管,運算能力更強大。ENIAC重30噸,占地170平方米,體積3000立方英尺,用了18 000個電子管,功率25KW,主要用于計算彈道和研制氫彈。它的負責人是John W. Mauchly和J. Presper Eckert。如果你有幸成為ENIAC的程序員,你將不得不用機器碼和穿孔卡片編寫所有的程序,并且直接在內(nèi)存中讀寫指令和數(shù)據(jù),安排和維護內(nèi)存的分配。即使增加一行代碼,也必須重新考慮所有指令和數(shù)據(jù)在內(nèi)存中的分配。編制的程序完全像天書,全由0和1組成。關于“誰是世界上第一臺真正意義上的電子數(shù)字計算機之父”的爭論及其專利訴訟歷程,讀者可上Internet搜索一下“Atanasoff-Berry Computer”即可得知歷史的真相。現(xiàn)在,比較客觀的結論是:世界上第一臺通用電子數(shù)字計算機是由阿塔那索夫設計并由莫克利和艾克特完全研制成功的。1949年的EDVAC(Electronic Discrete Variable Computer)是第一臺使用磁帶的計算機。這是一個突破,專家們可以在其上多次編寫和存儲程序。不過你還是必須使用機器碼。這一年的科學雜志做了一個大膽的預測:“未來的計算機不會超過1.5噸”。1952年,對于程序設計來說是具有重要里程碑意義的一年。MIT(美國麻省理工學院)在Whirlwind 系統(tǒng)上使用了符號地址,開始使用匯編語言來編寫程序。Whirlwind被美國空軍用于控制實時防御系統(tǒng)。1954年,IBM公司的John Backus和他領導的研究小組開始研制Fortran(Formula Translation)語言,這是一種用于科學計算的編程語言。Fortran語言于1957年研制完成。Fortran支持一些最常用的編碼方式,如算術表達式、邏輯運算、過程調(diào)用、循環(huán)和條件等。相對于匯編語言來說,F(xiàn)ortran可以被稱為高級語言,它提高了程序員的編程效率。Fortran歷經(jīng)變遷,如今演變成為Visual Fortran。1958年,Robert Noyce(Intel公司的創(chuàng)始人)發(fā)明了集成電路。1959年 Grace Murray Hopper開始研制COBOL(Common Business-Oriented Language)語言,并于1961年完成。COBOL在銀行系統(tǒng)和許多大型企業(yè)中得到了廣泛的應用。直到今天,仍然有許多用COBOL編制的程序在大型機上運行。1960年,來自丹麥、英國、法國、德國、荷蘭、瑞士和美國的13名代表舉行了一次國際會議,會后在計算機權威刊物CACM上發(fā)表了關于算法語言Algol 60的報告。Algol是一種用日常英語及與常用數(shù)學表達式相近的形式表現(xiàn)算法的語言,沒有輸入輸出語句,全部以過程的形式進行描述,并以塊結構為基礎。Algol是第一個結構化編程語言。1961年,IBM的Kennth Iverson推出APL編程語言,專門用于矩陣運算。1965年,Thomas E. Kurtz和John Kemeny研制了BASIC(Beginners All Purpose Symbolic Instruction Code)語言。BASIC特別適合于計算機教育和初學者使用,后來發(fā)展成為Visual Basic,為Microsoft公司掙了很多錢。1967年,Niklaus Wirth開始在Algol基礎之上開發(fā)Pascal語言,于1971年研制完成。Pascal后來成為Borland公司用來對抗Microsoft公司的利器。但是這個時候,無論是Microsoft還是Borland都還沒有出世。1968年,Seymour Paper和他的研究小組在MIT開發(fā)了LOGO語言。LOGO語言非常有趣,適用于教育領域。LOGO語言的標志是一個有趣的忍者神龜。1969年,ARPANET計劃啟動(Advanced Research Projects Agency Network),這是現(xiàn)代Internet的雛形。1970年,許多大學和商業(yè)部門開始接入ARPANET。Internet的發(fā)展又帶動了一批新的語言,但這是20年之后的事了。1970年,Ken Thomson和Dennis Ritchie開始研制UNIX操作系統(tǒng)。1971年11月15日,Intel公司的Marcian E. Hoff研制成功第一塊微處理器4004。它包含2300個晶體管,是一個4位系統(tǒng),時鐘頻率108kHz,每秒執(zhí)行6萬條指令。1972年 ,貝爾實驗室發(fā)明了C語言。C兼有低級語言和高級語言的功能,被人們稱為中級語言。C是一個功能強大的編程語言,它最初因被用于開發(fā)UNIX系統(tǒng)而聞名于世。到20世紀80年代,貝爾實驗室又發(fā)明了C+語言。C和C+被譽為是程序員的“正宗編程語言”,它們的廣泛應用極大地推動了軟件業(yè)的發(fā)展。1974年這一年發(fā)生了許多重大的事件。4月1日Intel發(fā)布了8位微處理器芯片8080。12月,MITS發(fā)布了Altair 8800,這是第一臺商用個人計算機,價值397美元,內(nèi)存只有256字節(jié)。同年,Bill Gates和Paul Allen開始開發(fā)第一個在MITS 的Altair計算機上運行的BASIC程序,他們手頭甚至沒有Altair計算機。1975年,Bill Gates和Paul Allen創(chuàng)辦了Microsoft公司。要是那個時候人們買了Microsoft公司的股票該有多好啊!1976年,Zilog推出Z80處理器,這是一個8位的微處理器。CP/M就是基于Z80的操作系統(tǒng)。1979年,Jean Ichbiah 研制了Ada語言,被廣泛用于美國軍方。同年,IBM公司眼看著個人計算機市場被蘋果等電腦公司占有,決定開發(fā)自己的個人計算機。Microsoft公司不但提供了用于IBM-PC的BASIC語言,還承擔了操作系統(tǒng)的開發(fā)。1981年8月,IBM推出了首款IBM-PC,同時也為Microsoft的崛起鋪平了道路。在IBM-PC發(fā)布的同時,MS-DOS 1.0和PC-DOS 1.0也一起發(fā)布。Microsoft受IBM委托開發(fā)DOS操作系統(tǒng),他們從Tim Paterson那里購買了一個叫86-DOS 的程序并加以改進。從IBM賣出去的叫PC-DOS,從Microsoft賣出去的叫MS-DOS,Microsoft精明地保留了繼續(xù)開發(fā)的權利。DOS的最初版本里Bug很多,以至于被稱為“Dirty Operation System”,但這卻是Microsoft獨霸PC操作系統(tǒng)的開始。1983年,Borland公司成立,其創(chuàng)始人是Philippe Kahn和Anders Hejlsberg,他們合作研制了Turbo Pascal,并在著名的Byte雜志上登廣告。售價49.99美元的Turbo Pascal是一個革命性的產(chǎn)品,它能夠在RAM中常駐運行,又具有閃電般的編譯速度,成為當時PC上最流行的開發(fā)工具。Borland也由此邁上了其影響PC軟件開發(fā)工具十幾年的道路。1985年,Microsoft發(fā)布了Windows 1.0。最初的Windows存在很多嚴重的Bug,不僅少有人用而且被人譏笑。一直熬到1993年,Windows 3.1才獲得成功。Windows的圖形用戶界面與Apple公司的類似,以致被Apple公司控告。訴訟一直持續(xù)到1997年8月,Apple遇到了嚴重的財務危機,Microsoft伸出資本的雙手,向Apple注資1.5億美元,換來了Apple撤銷其控訴。1989年,歐洲物理粒子研究所的Tim Berners-Lee 創(chuàng)造了World Wide Web的雛形,HTML語言開始流行,大大地推動了Internet的發(fā)展。1994年,Netscape 1.0 瀏覽器發(fā)布。1995年8月,Microsoft發(fā)布了32位的多任務操作系統(tǒng)Windows 95,該版本取得了巨大的成功。同年,號稱“一次編譯,到處運行”的Java語言誕生。1995年12月,Netscape發(fā)布了JavaScript。1996年1月,Netscape Navigator 2.0發(fā)布,這是第一個支持JavaScript的瀏覽器。2002年,Microsoft發(fā)布了.NET,開始與Java陣營競爭。有人繪制了一張比較直觀的編程語言關系圖,如圖2-1所示。4 Page 56:“4.3 類型轉換”一節(jié)上面一段末尾應從“關于復合.”處另起一行并縮進兩個字;5 Page 58:示例4-6,代碼用下列代碼替換:class Baseprivate:int m_a;int m_b;/ 示例Derived objD1;Base objB1 = objD1; / 見圖4-3左圖Derived *pD1 = &objD1;class Derived : public Base int m_c ;Base *pB1 = pD1; / 見圖4-3右圖6 Page 76:示例4-13上半部分最后一行“delete a;”要右移4格對齊;下半部分最后一行左移4格對齊;7 Page 78:示例4-15的代碼完全替換為下列代碼:int main()unsigned long a, b, c = 0; /* 兩個整數(shù)和臨時變量 */unsigned long lcm = 0, gcd = 0; /* 最小公倍數(shù)和最大公約數(shù) */while (1) printf ( Please input two positive integers(spacebar as separator): ); scanf ( %lu %lu, &a, &b ); if (a = 0 | b = 1 E = 0 |(E = 1 & A = 1 & D = 1)我們用另一個變量sum來表示組合空間中某一個組合能夠同時滿足的論斷個數(shù),如果出現(xiàn)了這樣一個組合它同時滿足了這5條論斷那么它就是我們要找的組合。當然,同時滿足所有論斷的組合可能不止一個,因此我們有必要搜索整個組合空間(雖然在本案中這種情況不應該存在,但是在做其它類似的搜索時不要忘記這一點)。程序見示例4-21。示例4-21#include int main (void) int count = 0; / 滿足所有條件的答案個數(shù) int sum = 0; / 累計滿足的條件個數(shù) int A, B, C, D, E; for ( A = 0; A 2; A+) for ( B = 0; B 2; B+) for ( C = 0; C 2; C+) for ( D = 0; D 2; D+) for ( E = 0; E = 1 ) ? 1 : 0; sum += ( E = 0 | ( E = 1 & A = 1 & D = 1 ) ) ? 1 : 0; if ( sum = 5 ) / 找到一個滿足所有條件的組合 count+; printf (/ This is the %d th answer:n, count); printf (Suspect A is %s.n, ( A = 1 ) ? a criminal : not a criminal); printf (Suspect B is %s.n, ( B = 1 ) ? a criminal : not a criminal); printf (Suspect C is %s.n, ( C = 1 ) ? a criminal : not a criminal); printf (Suspect D is %s.n, ( D = 1 ) ? a criminal : not a criminal); printf (Suspect E is %s.n, ( E = 1 ) ? a criminal : not a criminal); printf (n); return 0;輸出結果如下:/ This is the 1 th answer:Suspect A is not a criminal.Suspect B is not a criminal.Suspect C is a criminal.Suspect D is a criminal.Suspect E is not a criminal.10 Page 83:在“最后我們舉一個數(shù)值計算.。”一行前面插入“例5:數(shù)值計算?!保?1 Page 88:建議5-1中的示例代碼:兩個MAX和PI應該垂直對齊,后面的注釋也垂直對齊;12 Page 91:“C+程序”所在一行中:右邊的方法二和左邊的方法二要水平對齊,調(diào)整后后面的方法三和方法四也要分別與左邊的方法三和方法四水平對齊;13 Page 93:倒數(shù)第10行,將“定義和初始化每一個常量時,一次一個樣。”修改為“定義和初始化每一個常量一次?!?;14 Page 96:示例6-1:將“T是形參”修改為“_T是形參”;15 Page 103:將最后一行中的“chat”改為“char”;16 Page 104:倒數(shù)第三行,將“取值范圍是”改為“取值范圍是”,即將最后的右圓括號改為右方括號即可;17 Page 107:示例6-8中,后面的注釋行要垂直對齊;18 Page 115:示例6-16的代碼完全替換為下列代碼:#include / 求兩個整數(shù)a和b的最大公約數(shù)unsigned long gcd_2(unsigned long a, unsigned long b) if(b = 0) return a;else return gcd_2(b, a % b);int main(void)unsigned long a, b; /*兩個整數(shù)*/unsigned long lcm = 0, gcd = 0; /*最小公倍數(shù)和最大公約數(shù)*/ while (1) printf ( Please input two positive integers(spacebar as separator): ); scanf ( %lu %lu, &a, &b ); if (a = 0 | b = 0) printf ( Input error!n ); continue; else break; gcd = gcd_2(a, b);lcm = (a * b) / gcd;printf(Their Greatest Common Divisor is %lu.n, gcd);printf(Their Least Common Multiple is %lu.n, lcm);return 0;19 Page 122:示例7-1中,所有“cout .”行中的“:0x”要垂直對齊;20 Page 144:示例8-5右半邊“char ch; ”一行要縮進4格垂直對齊;21 Page 147:上方代碼中最后一個“:8”中間插入一個空格;22 Page 149:示例8-9中,將“sizeof(X) = 4”修改為“sizeof(X) = 8”;23 Page 154/155:圖8-6和圖8-7中m_price的長度應該是8字節(jié)而不是4字節(jié),這是個筆誤,所以分別用下面的圖替換即可:圖8-6圖8-724 Page 167:第(7)條中,“#define SQUARE(x)(x)*(x)”中間要插入幾個空格,即修改為:#define SQUARE(x) (x)*(x)“#define SQUARE(x)x * x”的中間也插入幾個空格,即修改為:#define SQUARE(x) x * x25 Page 168:第(8)條中,把“否則將導致變量的多次求值”替換為“否則可能導致變量多次求值,且結果可能與預期不符,因為復合表達式中子表達式的求值順序可能因具體編譯器的不同而不同?!?;26 Page 168:第(8)條中,把“其結果將是30而不是期望的25,這是因為展開的結果為:int x = (n+) * (n+);”替換為“其結果可能是30,也可能是25?!?;27 Page 170:示例9-2中,將下列代碼:#define FLAG_DOS2#define FLAG_UNIX1#define FLAG_WIN0#define OS1修改為:#define FLAG_DOS 2#define FLAG_UNIX 1#define FLAG_WIN 0#define OS 128 Page 181:建議10-5中,把“t”修改為t;29 Page 183:示例10-6用下面的代碼替換(主要是對齊問題):/* * 函數(shù)頭注釋 */void Function(float x, float y, float z) .if (.) . while (.) . / end of while . / end of if30 Page 193:將示例12-3的代碼替換為下面的代碼:typedef unsigned char BYTE;templateclass RingBuffer public: typedef size_t size_type; typedef GenericLocker _BufferLocker; RingBuffer() : m_pushPos(0), m_popPos(0), m_count(0) assert(N 0); m_pRingBuffer = new BYTEN; RingBuffer() delete m_pRingBuffer; RingBuffer(const RingBuffer& copy) : m_popPos(0) assert(N 0); m_pRingBuffer = new BYTEN; size_type rearLen = N - copy.m_popPos; if (rearLen = copy.m_count) :memmove(m_pRingBuffer, ©.m_pRingBuffercopy.m_popPos, copy.m_count); else :memmove(m_pRingBuffer, ©.m_pRingBuffercopy.m_popPos, rearLen); :memmove(m_pRingBuffer + rearLen, copy.m_pRingBuffer, copy.m_count - rearLen); m_pushPos = m_count = copy.m_count; RingBuffer& operator=(const RingBuffer& other) if (this != &other) _BufferLocker guard(m_mutex); RingBuffer temp(other); / invoke copy constructor _Swap(temp); / this-_Swap(); return (*this); bool is_full() const _BufferLocker guard(m_mutex); return (m_count = N); bool is_empty() const _BufferLocker guard(m_mutex); return (m_count = 0); size_type size() const _BufferLocker guard(m_mutex); return m_count; size_type capacity() const return N; size_type push(const BYTE *data, size_type length) assert(data != NULL); _BufferLocker guard(m_mutex); if (length = 0 | length (N - m_count) return 0; size_type rearLen = N - m_pushPos; / 尾部剩余空間 if (length m_count) return 0; size_type rearLen = N - m_popPos; / 尾部剩余數(shù)據(jù) if (length = rearLen) :memmove(buf, &m_pRingBufferm_popPos, length); m_popPos += length; m_popPos %= N; / 調(diào)整新的pop位置 else :memmove(buf, &m_pRingBufferm_popPos, rearLen); :memmove(buf + rearLen, m_pRingBuffer, length - rearLen); m_popPos = length - rearLen; / 調(diào)整新的pop位置 m_count -= length; return (length); void clear() _BufferLocker guard(m_mutex); m_pushPos = 0, m_popPos = 0, m_count = 0; private: BYTE *m_pRingBuffer; / buffer size_type m_pushPos; / 新的push位置:pushPos=(popPos+count)% N size_type m_popPos; / 新的pop位置 size_type m_count; / 有效字節(jié)數(shù) CriticalSectionm_mutex;31 Page 196:示例12-6中,三個class所在行對齊有問題,后面兩個class行要左移4空格垂直對齊;32 Page 199:圖12-1用下圖替換(原圖沒有使用斜體):33 Page 200:示例12-11中,class Eye的“public:”所在行左移4格垂直對齊,同時“void”所在行向右縮進4格;正數(shù)第13行“.返回其中任意一個接口指針”修改為“.返回其中任意一個接口的指針”;34 Page 201:上方class Head的private部分以m_打頭的部分要垂直對齊;35 Page 207:倒數(shù)第12和13行,請把“/(3)”和“/ OK!”垂直對齊;36 Page 210:示例12-19,最后一行向左移4格垂直對齊;37 Page 224:在“最后,我們來想一想:”之前插入如下的文字段落:這里還有幾個關于vptr的問題,讀者肯定想搞明白,那就是:“vptr在哪里被初始化?它的值會不會改變?為什么需要改變?在哪里改變?”。很顯然,由于vptr并非static成員,因此只能在構造函數(shù)中初始化在哪個類的構造函數(shù)中就被初始化為指向哪個類的vtable。由于一個派生類對象的構造函數(shù)會從每一個繼承分支的根類開始向下依次調(diào)用它的每一個基類的構造函數(shù),所以除了在根類的構造函數(shù)中vptr是被初始化的外,在后來的基類構造函數(shù)中實際上都是在不斷地被改寫以指向當前構造函數(shù)對應的基類的vtable。編譯器必須保證在類的每一個構造函數(shù)中(包括拷貝構造函數(shù))都要重新初始化或改寫vptr。vptr必須隨著對象類型的變化而不斷地改變它的指向,以保證其值和當前對象的實際類型是一致的。(你可以說Derived d;對象是Base類型的,但它更加是Derived類型的對象,所以d的真實類型是Derived,雖然它同時也是Base類型的)另外讀者肯定想知道:在構造函數(shù)和析構函數(shù)中能不能調(diào)用虛函數(shù)?如果調(diào)用了虛函數(shù),它們能按照我們期望的那樣執(zhí)行嗎?這就取決于vptr的初始化和改寫的時機了。試想,如果在構造函數(shù)中調(diào)用某個虛函數(shù)之前還沒有把vptr初始化或改寫為指向當前類的vtable,那么這個虛函數(shù)恐怕80%的情況下不是你期望調(diào)用的那個虛函數(shù)體,甚至會導致程序崩潰。另外20%的情況就是你在當前類中根本沒有改寫基類的那個虛函數(shù)。所以說,vptr肯定是第一個被初始化和改寫的成員在所有用戶代碼執(zhí)行之前進行。我?guī)缀蹩梢钥隙ǖ卣f,如果有程序員在某個多態(tài)類的構造函數(shù)中調(diào)用了某個虛函數(shù),不管這個虛函數(shù)是新增的還是來自于多態(tài)基類亦或是改寫自多態(tài)基類,那他肯定是想讓這個虛函數(shù)執(zhí)行動態(tài)綁定。這是沒有問題的,因為當程序執(zhí)行到這個構造函數(shù)中的時候,可以肯定當前對象已經(jīng)存在了,而且vptr已經(jīng)被正確初始化了,只要保證這個虛函數(shù)使用到的所有其他數(shù)據(jù)成員都在它被調(diào)用之前初始化好即可。那么在析構函數(shù)中,vptr則應該是在所有用戶代碼執(zhí)行完之后被改寫為指向其直接基類的vtable,或者說在所有用戶代碼執(zhí)行之前被重新改寫為指向當前類的vtable。這是必須要做的,因為一個對象在析構的過程中是沿著繼承分支向上依次退化為各個基類型對象直至根類對象的,所以析構函數(shù)中的虛函數(shù)調(diào)用不應該綁定到當前類的某個派生類的該虛函數(shù)的改寫版本上。程序員在一個類的析構函數(shù)中調(diào)用虛函數(shù),他可能會想:“呀!要是這個虛函數(shù)還能夠把當前類的派生類的這個虛函數(shù)的改寫版本調(diào)用起來,那就太酷了!”比如以Shape:Shape()為例,如果他打算這樣實現(xiàn):Shape:Shape() Draw(); / 他期望調(diào)用Rectangle:Draw()而不是Shape:Draw()!那么我可以毫不猶豫地告訴他:他的美夢會落空!這肯定將調(diào)用Shape:Draw()(假設Shape:Draw()不是純虛的或者有一個函數(shù)體)。其實大家從與構造函數(shù)執(zhí)行順序的相反順序去推理,就很容易明白這一點。如果上述調(diào)用真的如他所期望的那樣執(zhí)行了的話,很可能會導致程序崩潰!比如你定義了一個Rectangle對象如下:Rectangle rect; / 這里將調(diào)用Rectangle:Rectangle(),進而調(diào)用Shape:Shape()那么當執(zhí)行到Shape:Shape()的時候,rect對象已經(jīng)不再是Rectangle類型了,而是退化為Shape對象了(假設Shape不是抽象類)。雖然Rectangle:Draw()函數(shù)仍然存在,但是Rectangle新增的成員都已經(jīng)不存在了,此時如果再調(diào)用Rectangle:Draw(),肯定會出問題,所以編譯器不可能那樣去實現(xiàn)。所以,為了安全起見,建議大家盡量避免在構造函數(shù)和析構函數(shù)中調(diào)用虛函數(shù)。如果你真的想調(diào)用的話,我想總是可以找到其他的途徑來實現(xiàn)你的意圖,沒有必要鋌而走險。38 Page 233:上方“class B”行向左移4格垂直對齊;39 Page 235:將表13-1內(nèi)文字的字號都改為“小五”號,如果已經(jīng)是小五號那就不用改了;40 Page 270:把示例15-3中第8行到第13行分別左移4格;41 Page 275:把建議15-1中的“比如反跟蹤”修改為“(比如反跟蹤)”;42 Page 285:示例15-19的代碼用下列代碼替換(在第10行第一個Television后面加&字符):示例15-19void DeviceControllor:ControlThem(HomeElectricDevice& device)Command cmd = GetCommand();switch(cmd)case OPEN:case PLAY_VCD:try Television& tv = dynamic_cast(device);tv.PlayVCD(); / 現(xiàn)在能夠處理Television對象和任何派生自它的對象!catch(std:bad_cast&) MsgBox(This device cannot play VCD!);break;43 Page 297:示例16-10:最后的“catch”一行向左移4格對齊;44 Page 301:正數(shù)第6行末尾句號改為冒號;45 Page 3

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論