版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
本書作者根據自己學習C++的親身體會及多年教學經驗,用簡單的例子和簡練的敘述講解C++編程,別具特色。全書共分十八章,內容涉及對象的演化、數據抽象、隱藏實現(xiàn)、初始異常處理和運行時類型識別。本書作為正式和均非常優(yōu)秀,作為程序設計者的 目錄11111 第3 隱藏實 為什么C++會成 C++ 較好的 4444類555 句柄類(handle 5679 第4 初始化與清 方法應當提供什 起草:最小的方 前 責任驅動的設計對象建模技術為向OOP5 范圍分 管理 用返回值重 安全類型連 2C什么是6 內聯(lián)函數和編譯 減少 為用戶分配的 自動分 輸出流格式 第9 命名控 格式化算 建立算 輸入輸出流實 其他的類型指定 代碼生 C++第7 常 值替 頭文件里的 與C 指 指向const 第10 C++C++中的函數中的constconst 拷貝構造函 傳遞和返回地 const和 const 只讀能 可變的 小 練 8第1 然而計算機并不僅僅是一臺機器,它是心智放大器和另一種有表述能力的。這一點使它不很像機器,而更像我們大腦的一部分,更像其他有表述能力的,例如寫作、繪畫、雕刻、動畫制作或制作。面向對象的程序設計是計算機向有表述能力的發(fā)展中的一部分。本章將介紹面向對象程序設計(OOP)的基本概念,然后討論OOP開發(fā)方法,最后介紹使2章,然后再C++包含了比面向對象程序設計基本概念的內容,讀者應當在學習設計和開發(fā)程序之對象:特性+行為第一個面向對象的程序設計語言是60年發(fā)的Simula-67。其目的是為了解決模擬問題。類描述了一組有相同特性(數據元素)和相為(函數)的對象。類實際上就是數據類型,例如,浮點數也有一組特性和行為。區(qū)別在于程序員定義類是為了與具體問題相適應,而不是被迫使用已存在的數據類型。這些已存在的數據類型的設計動機僅僅是為了描述機器的存儲單元。程序員可以通過增添他所需要的新數據類型來擴展這個程序設計語言。該程序設計系統(tǒng)歡迎創(chuàng)建、關注新的類,對它們進行與內部類型一樣的類型檢查。這種方法并不限于去模擬具體問題。盡管不是所有的人都同意,但大部分人相信,任何程序都模擬所設計系統(tǒng)。OOP技術能很容易地將大量問題歸納成為一個簡單的解,這一發(fā)現(xiàn)產生了大量的OO語言,其中最著名的是Smalltalk—C之前最成功的OOP語言。的特性和行為,但是,一個類型可能包括比另一個類型的特性,也可以處理的消[1]這一描述部分引自我對《TheTaoofObjects(GaryEntsminger著)一書的介紹(或對消息進行不同的處理。繼承表示了基本類型和派生類型之間的相似性。一個基本類型具有所有由它派生出來的類型所共有的特性和行為。程序員創(chuàng)建一個基本類型以描述系統(tǒng)中一些對象的思想。由這個基本類型派生出其他類型,表達了認識該的不同途徑。例如,再生機要對進行分類。這里基本類型是“”,每件有重量、價值等等,并且可以被破碎、融化或分解。這樣,可以派生出更特殊的類型,它們可以有另外的特性(瓶子有顏色)或行為(鋁可以被壓碎,鋼可以被磁化(紙的價值取決于它的種類和狀態(tài)。程序員可以用繼承建立類的層次結構,在該層次結構中用類型術語來表述他需要解決的問題。第二個例子是經典的形體問題,可以用于計算機輔助設計系統(tǒng)或游戲模擬中。這里基本類是”形小、。體制、由此,可以派生出特殊類型的形體:圓、正方形、三角形等,它們中的每一個都有另外的特性和行為,例如,某些形體可以翻轉。有些行為可以不同(計算形體的面積。類型層次結構既體現(xiàn)了形體間的類似,又體現(xiàn)了它們之間的區(qū)別。用與問題相同的術語描述問題的解是非常有益的,這樣,從問題描述到解的描述之間就不需要很多中間模型(程序語言解決大型問題,就需要中間模型。面向對象之前的語言,描述問題的解不可避免地要用計算機術語。使用對象術語,類型層次結構是主要模型,所以可以從現(xiàn)實世界中的系統(tǒng)描述直接進入代碼中的系統(tǒng)描述。實際上,使用面向對象設計,人們的之一是從開始到結束過于簡單。一個已經習慣于尋找復雜解的、訓練有素的頭腦,往往會被問題的簡單性難住。多態(tài)當處理類型層次結構時,程序員常常希望不把對象看作是某一特殊類型的成員,而把它看作基本類型成員,這樣就可以編寫不依賴于特殊類型的代碼。在形體例子中,函數可以對一般所以這些函數能簡單地發(fā)送消息給一個形體對象,而不考慮這個對象如何處理這個消息。例如,可以派生出形體的一個新的子類,稱為五邊形,而不必修改那些處理一般形體的函數。通過派生新子類,很容易擴展程序,這個能力很重要,因為它極大地減少了軟件的花費。在面向對象的程序設計中,答案是巧妙的。編譯器并不做傳統(tǒng)意義上的函數調用。由非OOP編譯器產生的函數調用會引起與被調用碼的“”,對于這一術語讀者可能還聽,因為從來沒有想到過它。早意味著編譯器對特定的函數名產生調用,而連接器確OOP,在程序運行之前,編譯器不確定執(zhí)行代碼的地址,所以,當消息發(fā)送給一般對象時,需要采用其他的方案。運行之前不去確定被調用的代碼。編譯器保證這個被調用的函數存在,并完成參數和返回值的類型檢查,但是它不知道將執(zhí)行的準確代碼。為了實現(xiàn)晚,編譯器在真正調用的地方插入一段特殊的二進制代碼。通過使用存放在(14紹。這樣,每個對象就能根據一個指針的內容有不同的行為。當一個對象接收到消息時,它根據這個消息判斷應當做什么。程序員可以用關鍵字virtual表明他希望某個函數有晚的靈活性,而并不需要懂得操作概念:OOP程序像我們已經知道,用C語言編寫的過程程序就是一些數據定義和函數調用。要理解這種程序的含義,程序員必須掌握函數調用和函數實現(xiàn)的本身。這就是過程程序需要中間表示的原因。中間表示容易引起,因為中間表示的表述是原始的,更偏向于計算機,而不偏向于所解決的問題。C++向CC++main()會C程序更復雜。但令人吃驚的是,一個寫得很好的C++C程序更簡單和容易理解。程序員只會看到一些描述問題空間對象的定義(而不是計算機的描述,發(fā)送給這些對象的消息。這些消息表示了在這個空間的活動。面向對象程序設計的優(yōu)點之一是通過閱讀,很容易理解代碼。通常,面向對象程序需要較少的代碼,因為問題中的許多為什么C++會成C++C語言轉變成OOP語言(雖然這是最初的目的,而且還為了解決程序員,特是些在C語言中已經大量投資的程序員所的許多問題。人們已經對OOP語言有了這樣傳統(tǒng)的看法:程序員應當拋棄所知道的每件事情并且從一組新概念和新文法重新開始,他應當相信,最好丟掉所有來自過程語言的老行裝。從長遠角度看,這是對的。但從短期角度看,這些行裝還是有價值的。最有價值的可能不是那些已存在的代碼庫(給出合適的工具,可以轉變它C的每一件事,以適應新的語言,那么,幾個月內,他將C知識,并在這個基礎上擴展,那么他就可以繼續(xù)保持高效率,帶著已有的知識,進入面向對象程序設計的世界。因為每個有他己的序設模型所以個轉是的因此,++成功的原因是經濟上的:轉變到OOP需要代價,而轉變到C++較好的即便程序員在C++環(huán)境下繼續(xù)寫C代碼,也能直接得到好處,因為C++堵塞了C些,并提供更好的類型檢查和編譯時的分析。程序員必須先說明函數,使編譯器能檢查它們的使用情況。預處理虛擬刪除值替換宏,這就少了查找疵點的+個稱為references(),它允許對函數參數和返回值的地址進行更方便的處理。函數重載改進了對名字的處理,使程序員能對不同的函數使用相同的名字。另外,名字空間也加強了名字的控制。許多性能使與學習新語言有關的問題是效率的問題。所有公司都不可避免地因軟件工程師學習新語言C++是對C的擴充,而不是新的文法和新的程序設計模型。程序員學習和理解這些性能,逐漸應用并繼續(xù)創(chuàng)建有用的代碼。這是C++成功的最重要的原因之一。另外,已有的C代碼在C++中仍然是有用的,但因為C++編譯器更嚴格,所以,重新編譯運行有時,以程序執(zhí)行速度換取程序員的效率是值得的。假如一個金融模型僅在短期內有用,所以C++C程序員非常重視運行效率,這讓他們認為這個語言不太龐大,也不太慢。產生的代碼運行效率不夠時,程序員可以用C++C++不僅有與C相同的基本控制能力(和C++程序中直接寫匯編語言的能力),非正式的證據,面向對象的C++程序的速度與用C寫的程序速度相差在±10%之內,而且常常更接近。為適合于某問題而設計的類當然能更好地表達這個問題。這意味著寫代碼時,程序員是在用問題空間的術語描述問題的解(,而不是用計算機的術語,也就是解空間的術語,描述問題的解(器。程序員所涉及的是較的概念,一行代碼能做的事情。易于表達所帶來的另一個好處是易于。據,在程序的整個生命周期中,占了花費的很大部分。如果程序容易理解,那么它就更容易,還能減少創(chuàng)建和文檔的花費。C++的主要目標是讓程序員能更容易地使用庫,這是通過將庫轉換為新數據類型(類)來完成的。引入一個庫,就是向該語言增加一個新類型。編譯器負責這個庫如何使用,保證適當的初始化和清除,保證函數被正確地調用,因此程序員的精力可以集中在他想要這個庫做什么,而不是如何做上。因為程序的各部分之間名字是的,所以程序員想用多少庫就用多少庫,不會有像C語是重用庫代碼特別有用的工具。用模板設計的類型很容易與其他類型一起工作。因為模板對程錯誤在C語言中,錯誤處理聲名狼藉。程序員常常忽視它們,對它們束手無策。如果正在建大而復雜的程序,沒什么比讓錯隱藏在某處,不它來自何處更的了。C++異處理(見第17章的內容)BASIC對于某些類型的問題能很快解決,但是如果這個程序有幾頁紙長,或者超出該語言的正常解題范圍,那么它可能算不出結果。C語言同樣有這樣的限制,例如當程序超過50000行時,名字就開始成為問題。簡言之,程序員用光了函數和變量名。另一個特別糟糕的問題是如果C語言中存在一些小漏洞—錯誤藏在大程序中,要找出它們是極其的。沒有清楚的文字告訴程序員,什么時候他的語言會失效,即便有,他也會忽視它們。他不說“我的BASIC程序太大,我必須用C重寫”,而是試圖硬塞進另外幾行,增加額外的性能。所以額外的花費就悄悄增加了。設計C++的目的是為了輔助大程序設計,也就是說,去掉小程序和大程序之間復雜性的分界。當程序員寫 o-world類實用程序時,他確實不需要用OOP、模板、名字空間和異常處理但當他需要的時候,這些性能就有用了。而且,編譯器在排除錯誤方面,對于小程序和大程序一樣有。OOP中,方法學是一個有許多實踐的領域。因此,在程序員考慮采用某一方法之前,了解該方法將要解決的問題是很重要的。對于C++,有一點是確實的:它本身就是希望減少程序表達的復雜性。從而不C++認識到“方法學”一詞含義太廣是很重要的。實際上,設計和編寫程序時,無論做什么都在使用法。只不過因為它是程序員自己的方法而沒有。但是,它是程序員編程中的一個過程。如果過程是有效的,只需要用C++做很小的調整。如果程序員對他的效率和調整復雜的,另一個是程序的分析,為了將來理解和程序而產生的。創(chuàng)建和都是程序生命期的內部程序設計的演化(C++只是其中的一步)從程序設計模型強加于內部開始,也就是允許程序員為內存位置和機器指令取別名。這是數字機器程序設計的一次飛躍,帶動了其他方面的發(fā)展,包括從初級機器中抽象出來,向更方便地解決手邊問題的模型發(fā)展。不是所有這些發(fā)展都能流行,于學術界并延伸進計算機世界的思想常常依賴于所適應的問題。命名子程序的創(chuàng)建和支持子程序庫的連接技術在50年代向前飛躍發(fā)展,并且孕育出了兩個語言,它們在當時產生了巨大沖擊,這就是為科學工作者使用的FORTRAN(FORmula-TRANslation)和為商業(yè)者使用的COBOL(COmmonBusiness-OrientedLanguage。純計算機科學中很成功的語言是Lisp(List-Processing),而面向數學的語言應當是APL(AProgrammingLanguage這些語言的共同特點是對過程的使用。Lisp和APL的創(chuàng)造專注于語言的高雅—語言的“missionFOTRAN和COBOL的創(chuàng)造是為了解決專門的問題,當這些問題變得更復雜,有新的問題出現(xiàn)時,它們又得到了發(fā)展。甚至它們進入衰FRTRAN和COBOL的版本都面向對象進行了擴充(后時髦哲學的基本原則是:任何具有自己獨特生活方式的組織,其主要目標就是使這種生活方式永存。命名子程序在程序設計中起了重要作用,語言的設計圍繞著這一原則,特別是Algol和Pascal。同時另外一些語言也出現(xiàn)了,它們成功地解決了程序設計的一些子集問題,并將它們有序排列。最有趣的兩個語言是Prolog和FTH。前者是圍繞著推理機而建立的(在其他語言中常常稱作庫。后者是一個可擴充語言,允許程序員重新形成這個語言,以適應所解決的問題,觀上類于面對象序設。FOTH還可以改變語言,因而很難,并且是內部原則概念最純正的表達,它強調的是問題一時的解,而不是對這個解的。人們還創(chuàng)造了其他許多語言,以解決某一部分的程序設計問題。通常,這些語言以特定的BASIC(BeginnersAll-purposeSymbolicInstructionCode)是在60年代設計的,目的是使程序設計對初學者更簡單。APL的設計是為了數學處理。兩種語言都能夠解決其他問題,而關鍵在于它們是否是這些問題集合最理想的解。有一句笑話是,“帶著錘子三年,BASIC或APL語言,特別是,當最終期限很短且這個解的生命期有限時,它就是我們問題最好的解。然而,最終考慮兩個因素:復雜性的管理和(將在下一部分討論。即這種語言首先是為某一領域開發(fā)的,而程序員又不愿花很長時間來熟悉這門語言,其結果只能使程序越來越長,使手頭的問題屈服于語言。界限是模糊的:誰能說什么時候您的語言會使您失望呢?這不是馬上就出現(xiàn)的。問題的解開始變長,并且對于程序員更具性。為知道語言大概的限制,你得,這種聰明變成了一種標準,也就是“為了使該語言工作而努力”。這似乎是人類的操作方式,而不是遇到缺陷就抱怨,并且不再稱它為缺陷。最終,程序設計問題對于求解和變得太了,即求得的解太昂貴了。人們最終明白了,程序的復雜性超出了我們能夠處理的程度。盡管一大類程序設計要求開發(fā)期間去做大部分工作并創(chuàng)建要求最小的解(或者簡單地丟掉這個解,或者用不同的解替換它,但這只是了,服務就必須隨著變化。這樣,當第一版本開始運行時,項目并沒有結束。項目是一個不斷外部為了更新和改善程序,需要更新思考問題的方法。它不只是“我們如何讓程序工作”,而是“我們如何讓程序工作并且使它容易改變”。這里就有一個新問題:當我們只是試圖讓程序工作時,我們可以假設開發(fā)組是穩(wěn)定的(總之,我們可以希望這樣,但是,如果我們正在考慮程序的整個生命期,就必須假設開發(fā)組成員會改變。這意味著,新組員必須以某種方式學習原程序的要點,并與老組員互相通訊(也許通過。這樣,該程序就需要某種形式的設計文檔。因為只想讓程序工作,文檔并不是必需的,所以還沒有像由程序設計語言強加于程序那樣的、強加于創(chuàng)建文檔的規(guī)則。這樣,如果要求文檔滿足特定的需要,就必須對文檔強加外部原(形式的爭論.比對“最好”程序設計語言的爭論更激烈。決定外部原則時,頭腦中的重要問題是“我準備解決什么問題”。問題的根本就是上面所說的“我們如何讓它工作和使它容易改變”。然而,這個問題常常有多種解釋:它變成了“我如何才能與FoobleBlah文檔規(guī)范說明一致,以使會為此給我撥款”。這樣,外部原則的目的是為了建立文檔,而不是為了設計好的、可的程序。文檔竟然變得比程序本身更重要了。被問到未來一般和特殊的計算的方向時,我會從這樣的問題開始:哪種解花費較少?假設這個解滿足需要,價格的不同足以使程序員放棄他當前做事情的習慣方式嗎?如果他的方法包括在項目分析和設計過程中所創(chuàng)建的每個文檔,并且包括當項目進化時這些文檔,那么當項目更新時,他的系統(tǒng)將花費很大,但是它能使新組員容易理解(假設沒有那么多的使人害怕閱的文檔。這樣創(chuàng)建和方法的花費會和它打算替代方法的花費一樣多。外部結構系列的另一個是最小化方法為完成設而進行足夠的分析,然丟掉它們,使得程序員不再花時間和錢去它;為開始編碼而做足夠的設計,然后丟掉這個設計,使得程序員不再花時間和錢去這些文檔;然后使得代碼是一流的和清晰的,代碼中只需要最少新組員只需花費很少的時間(總之,沒有人真地理解它們,所以他能較快地參與工作。即便不文檔,丟掉文檔也不是最好的辦法,因為這畢竟是程序員所做的有效工作。某但是,代碼包含了我們實際上希望外部原則所產生的事物的本質:通訊。我們只是希望能與改進這個程序的新組員通訊就足夠了。但是,我們還想使花費在外部原則上的錢最少,因為最終人們只為這個程序所提供的服務付錢,而不是為它后面的設計文檔付錢。為了真正有用,外部原則應當做比只產生文檔的事情—它應當是項目組成員在創(chuàng)建設計時為了討論問題而采用的通訊方法。理想的外部原則目標是使關于程序分析和設計的通訊更容易。這對于現(xiàn)在為這而為了產生好的設計。發(fā)者為機器做大量工作的外部原則似乎從一開始就注定要失敗。成功的方法(也就是人們習慣的方法)它幫助人們進行分析和設計。這就是,用這種方法比用別的方法對分析和設計中的思考和通訊要容易得多。目前的效率和采用這種方法后的效率應當明顯不同。否則,人們可能還留在原地。還有,它的使用必須足夠簡單,不需用手冊。當程序員正在解決問題時,要考慮簡單性,而不管他適用于符號還是技術。沒有短期回報,就不會加強投資。在通向目標的可見的進展中,沒有短期回報,人們就不會感到采用法能使效率提高,就會回避它。不能把這個進展誤認為是從一種中間形式到另一種中間形式的變換。程序員可以看到他的類,連同類之間互相發(fā)送的消息一起出現(xiàn)。為創(chuàng)造法,就像武斷的約束,因為它是簡單的心理狀態(tài):人們希望感到他們正在做創(chuàng)造性的工作,如果某種方法妨礙他們而不是幫助他們飛快地接近目標,他們將設法繞過這種方法。在方法學上我的觀點之一是聽眾對“小”的理解因人而異。雖然這種看法并不全對,但它包含一個正確的:我們所需要的原則與我們正在努力解決問題的量級有關。小項目完全不需要外部原則,這不同于個別程序員正在解的生命期問題的模式。涉及很多人的大項目會使人們之間有一些通訊,所以必須使通訊具有形式化方法,以使通訊有效和準確。麻煩的是介于它們之間的項目。它們對外部原則的需要程度可能在很大程度上依賴于項目的復雜性和開發(fā)者的經驗。確實,所有中等規(guī)模的項目都不需要忠實于成方法,即產生許多報告和很多文檔。一些項目也許這樣做,但許多項目可以僥幸成功于“方法學簡化”代碼多而文檔少。我們面前的所有方法學的復雜性可以減少到80%~20%的(或更少的)規(guī)則。20%些方法學。如果我們的設計是充分的,并且也不可怕,那么我們也許不需要方法學或不全OOP現(xiàn)在提出一個更有意義的問題。為了使通訊方便,假設方法學是需要的。這種關于程序的元通訊是必須的,因為程序設計語言是不充分的—它太原始,趨向于機器范例,對于談論問題不很有用。例如,過程程序設計方法要求用數據和變換數據的函數作為術語談論程序。因為這不是我們討論實際問題的方法,所以必須在問題描述和解描述之間翻譯來翻譯去。一旦得到了一個解描述并且實現(xiàn)了它,以后無論何時對這個解描述做改變就要對問題描述做改變。這意味著必須從機器模式返回問題空間。為了得到真正可的程序,并且能夠適應問題空間上的改變,這種翻譯是必須的。投資和組織的需要似乎要求某種外部原則。過程程序的最重要的方法學是結構化技術。例如,在氣候控制大樓中的空氣調節(jié)器就變成了氣候調節(jié)程序的空氣調節(jié)器,自動調溫器(這是按做的,與OOP不一致。突然,從問題空間到解空間的翻譯變成了次要問題??梢韵胂?,在程序分析、設計的每一階段,能使用相同的術語學、相同的描述,這樣,這個問題就變成了“如果文檔(程序)能夠充分地描述它自身,我們仍然需要關于這個文檔的文檔嗎?”如果OOP這個論點也為一個思想實驗所揭示。假設程序員需要寫一些小實用程序,例如能在文本文(就像在第6章的后幾頁上可找到的那樣最的要花費幾小時寫?,F(xiàn)在假設回50年,個項目必須用機器語言匯編語言來寫50年代需要大量的外部原則和管理,現(xiàn)在不需要了。顯然,工具的發(fā)展已經極大地增加了我們不用外部原則解決問題的復雜性這并不是說可以不需要外部原則,有用的OOP外部原則解決的問題與有用的過程程序設計OOP方法的目標首先必須是產生好的設計。好設計不僅要促進重用,而且它與項目的各級開發(fā)者的需要是一致的。這樣,開發(fā)者就會更喜歡采用這樣的系統(tǒng)。讓我們基于這些觀點考慮OOP設計方法中的一些問題。對象的設計不限于寫程序的時期,它出現(xiàn)在一系列階段。有這種觀點很有好處,因為我們不再期望設計立刻,而是認識到,對對象做什么和它應當像什么的理解是隨著時間的推移而產生的。這個觀點也適用于不同類型程序的設計。特殊類型程序的模式是通過一次又一[1]。同樣,對象有自己的模式,通過理解、使用和重用而形成。對象發(fā)現(xiàn)這個階段出現(xiàn)在程序的最初分析期間。可以通過尋找外部因素與界線、系統(tǒng)中的元素副本和最小概念單元而發(fā)現(xiàn)對象。如果已經有了一組類庫,某些對象是很明顯的。類之間的共同性(暗示了基類和繼承類,可以立刻出現(xiàn)或在設計過程的后期出現(xiàn)。對象裝配我們在建立對象時會發(fā)現(xiàn)需要一些新成員,這些新成員在對象發(fā)現(xiàn)時期未出系統(tǒng)構造對對象的要求可能出現(xiàn)在以后階段。隨著不斷的學習,我們會改進我們系統(tǒng)擴充當我們向系統(tǒng)增添新的性能時,可能發(fā)現(xiàn)我們先前的設計不容易支持系統(tǒng)擴對象重用這是對類的真正的重點測試。如果某些人試圖在全新的情況下重用它,他們會發(fā)現(xiàn)一些缺點。當我們修改一個類以適應更新的程序時,類的一般原則將變得更清楚,直到我們有了一個真正可重用的對象。[1]參看DesignPatterns:ElementsofReusableObject-OrientedSoftwarebyErich etal.,Addison-Wesley,1995和簡單的類開始,當我們對它有了較好地理解時再擴展這個類接口,但不可能簡化已存在的類接口。由于不同的原因,方法承諾的東西往往比它們能夠提供的東西多得多。這是不幸的,因為當策略和不實際的期望同時出現(xiàn)時程序員會疑神疑鬼。一些方法的壞名聲,使得程序員丟棄了的許諾是“這個方法將解決您的所有問題”。這一許諾也很可能用這樣的思想表達,即一個方法將解決實際上不存在解的問題,或者至少在程序的設計領域內沒有解的問題:一個貧窮的,疲憊的、互相疏遠或的項目組成員;不充分的時間和資源;或試圖解決一個實際上不能解的問題(資源不足。最好的方法學,不管它許諾什么,都不解決這些或類似的任何問題。無論OOP還是C++,都無助于這樣的問題。不幸的是,在這種情況下管理員是樣對報1],他是最動搖的。這就是方法應當成為的東西。提高生產效率不僅取決于管理容易和花費不大,而且取決于一開始就創(chuàng)建好的設計。由于一些方法學的創(chuàng)造動機是為了改善,所以它們就片面地強調OOP設計也應當容易,但這它的附加作用。不管為特殊方法提出什么要求,它都應當提供這一節(jié)所列出的基本功能:允許為討論這個項目將完成什么和如何做而進行通訊的約定;支持項目結構化的系統(tǒng);能用某抽象形式描述項目的一組工具(使得程序員能容易地觀察和操作項目。如過去介紹過的,一個更微妙的問題是該方法對待最寶貴資源—對于很小的項目組,可以用緊密接觸的方式自然維持通訊。這是理想的請況。C++的最大的好處之一是它可以使項目由很少的項目組成員建立,因此,明白表示的通訊能使變得容情況并不總是這樣理想,有可能項目組成員很多,項目很復雜,這就需要某種形式的通訊原則。方法提供一種在項目組成員之間形成“約定”的辦法??梢杂脙煞N方式看待這樣的約定:1)的約定基于參與的當事人之間互有疑問,以使得沒有人出格且每個人都做應該做的事情。約定清楚地說明,如果他們不做這些事,會出現(xiàn)壞的結果。這樣看待任何約定,我們就已經輸了,因為我們已經認為其他人是不可信賴的了。如果不能信任,約定并不能確保好的行為。2)信息的約定是一種努力,使每個人都知道我們已經在哪些方面取得了一致的意見。這是對通訊的輔助,使得每個人能看到它并說,“是的,這是我認為要做的事情。它是協(xié)[1]AreferencetovampiresmadeinTheMythicalMan-Month,byFredBrooks,Addision-Wesley,1975符號應當盡可能少?!斑^多的噱頭使得軟件變壞”系統(tǒng)設計和類設計是互相的問題。類是可重用工具,而系統(tǒng)是對特殊問題的解(雖類設計符號是必須的嗎?由C++語言提供的類表達對大多數情況是足夠的。如果符號在保持符號簡單。我們想用我們的方法做的所有事情基本上就是發(fā)現(xiàn)對象及其如何互相連接以形成系統(tǒng)。如果一個方法或符號要求的東西,則應當問一問,該方法花費我們的時間是否合理。我的朋友MichaelWilk來術界,也許并不具備做評判的資格(從某個人那里聽說的新觀點,但他觀察到,項目、開發(fā)組或公司擁有的最重要的資源是積極性。不管問題如何過去失敗多么嚴重,工具多么原始或不成套,積極性都能克服這些。不幸的是,各種管理技術常常完全不考慮積極性,或因為不容易度量它,就認為它是“不重要”的因素,他們認為,如果管理完善,項目就能強制完成。這種認識有開發(fā)組積極性的作用,因為他們會感到公司除了利益動機以外就沒有感的東西了。一旦發(fā)生這種現(xiàn)象,。在選擇任何方法之前,從并不想方法的人那兒得到意見是有幫助的。不真正地理解我們想要法是為了做什么或它能為我們做什么,那么采用法很容易。其他人正在用它,這似乎是很充足的理由。但是,人們有一種奇怪的心理:如果他們相信某件事能解決他們的問題,他們就將試用它(這是經驗,是好的。但是,如果它不能解決他們的問題,他們可能加倍地努力,并且開始大聲宣布他們已經發(fā)現(xiàn)了偉大的東西(這是否定,是不好的。這個假設是,如果見到同一條船上有其他人,就不感到孤單,即便這條船哪兒也不去。這并不是說所有的方法學都什么也不做,而是用精神方法使程序員到牙齒,這些方法為我們提供這些精神。(SoftwareCreativity,RobertGlass編,Prentice-Hall,199Glass已經寫過的短文和文章以及收集到的東西組成的(.J.uger是一個撰稿者,反映出他在該上多年的思考和研究。他們愉快地說明什么是必須的,并不東拉西扯和掃我們的興,不說空話,而且,這里有幾百篇參考文獻。所有的[1。(Peoplear,TomDemarcoTimothyLiter編,DorsetHoue,1987有軟件開發(fā)方面的背景,而且本書大體上是針對項目和開發(fā)組的,但是這本書的重點是人和他們的需要方面,而不是技術和技術的需要方面。他們談論創(chuàng)造一個環(huán)境,在其中人們是和這本書后面的觀點是對程序員在采用XYZ方法,然后平靜地做他們總是做的事情時微笑和點頭(Complexit,M.Mitc Waldrop編,Simon&Schuster,1992。此書集中了SantaFe,NewMexico的一組持不同觀點的科學家,討論單個原則不能解決的實際問題(經濟學中的市場、生物學的生命原始形式、為什么人們做他們在社會中應做的事情,等等。通過物理學、經濟學、化學、數學、計算機科學、社會學和其他學科的交叉,對這些問題的一種多原則途徑正在發(fā)展。更重要的是,思考這些極其復雜問題的不同方法正在形成。拋開數學的確定性,人們想寫一個所有行為的方程,首先觀察和尋找一個模式,用任何可能的模擬這個模式(例如,這本書編入了遺傳算法。我相信,這種思維是有用的,因為我們正在對管理越來越復雜軟件目的方法做科學察。我首先,這一點沒有證明過。我并不許諾—起草是起點,是其他思想的,是思想試驗,盡管這是我在大量思考、適量閱讀和在開發(fā)過程中對自己和其他人觀察之后形成的看RobertMcKee2]的教學中,最初針對熱心熟練的劇作家們,也針對小說家和編劇。后來我發(fā)現(xiàn),程序員與這個有少量令人拍案稱奇的上口小說,其他許多小說都很平庸,但有技巧,得到,大量不上口的小說得不到。當然,小說要描述,而程序要編寫。作家還有一些在程序設計中不太出現(xiàn)的約束:他們一般單獨工作或可能在兩個人的組中工McKee個目標是將花費在編劇上的時間從一年減少到六個月,在這個過程中極大地提高編劇的質量。軟件開發(fā)者可以有類似的目標。另外一本好“前景”的書是ObjectLessonsTomLove著,SIGSBooks,1993ThroughTwoArts,Inc.,12021WilshireBlvd.Suite868,LosAngeles,CA90025前與典型的過程語言(和大量已存在的語言)不同,C++語言和語言性能中有許多防護,程序員能建立自己的防護。這些防護意在防止程序員創(chuàng)建的程序破壞它的結構,無論在創(chuàng)建它的整個期間還是在程序期間。不管分析得如何透徹,這里還有一些有關系統(tǒng)的事直到設計時還沒有揭示出來,的直到程序完成和運行時還沒有揭示出來。因此,快速通過分析過程和設計過程以實現(xiàn)目標系統(tǒng)的測試是重要的。根據第一點,這比用過程語言更安全,因為C++中的防護有助于防止“面條”代碼的創(chuàng)建。著重強調第二點。由于歷史原因,我們已經用了過程語言,因此在開始設計之前開DBMS時,徹底DBMS是一類具有良好形式且容易理解的問題。在這一章中討論的這類程序設計問題是ild-car變體問題,它不只簡單地重新形成已知解,而是包括一個或多個ild-card因素—1]手設計之前徹底地分析ild-card問題會導致分析癱瘓,因為在分析階段沒有足夠的信息解決這類問題。解這樣的問題要求在整個周期中反復,要(以產生感性認識,因為程序員正在做新事情并且有較高潛在回報結果是,由盲目“闖”預備性實而產生是它反而能減少在ild-ard項中的,為人較早地現(xiàn)一特殊設計否可。這個方法的目標是通過建議解處理wild-card問題,得到最快的開發(fā)結果,使設計能盡早地被證明或反證。這些努力不會白費。這個方法常常建議,“建立一個解,然后再丟掉它”。用OOP,可能仍然丟掉一部分,但是因為代碼被封裝成類,不可避免地生產一些有用的類設計和第一次反復中發(fā)展一些對系統(tǒng)設計有價值的思想,它們不需要丟掉。這樣,對某一問題快速地過一遍不僅產生對下一次分析、設計的重復重要的信息,而且也為下一次的重復過程創(chuàng)這個方法的另一性能是能對項目早期部分的集體討論提供支持。由于保持最初的文檔小而簡明,所以最初的文檔可以由小組與動態(tài)創(chuàng)建該描述的通過幾次集體討論而創(chuàng)建,這不僅要求每個人的投入,而且還鼓勵開發(fā)組中的每個人意見一致。也許更重要的是,它能在較高的積極性下完成一個項目(如先前注意到的,這是最基本的資源。作家的最有價值的計算機工具是字處理器,因為它容易支持文檔的結構。對于程序設計項目,程序的結構通常是由某形式的分離的文檔來表述的。因為項目變得更復雜,所以文檔是必Brooks[2]獨立文檔的傻念頭—而我們在程序設計文檔方面的實踐了我們自己的。我們典型努是序器讀式一立讀文檔?”我們認為,使用熟悉的工具和思維模式是非常重要的 OOP的改變正著由它自己引我估計這樣的項目的主要規(guī)則:如果多于一張wd-card,則不計劃它要費多長時間和它花費多少。這里有太多的自由度。TheMythicalMan-Month,出處同上的。較早的OOP方法學已經因為使用精細的圖形符號方案而受挫了。我們不可避免地要大量改變設計,因為須改變設計以避免棘手的問題,所以用很難修改的符號表示設計是不好的。只是最近,才有處理這些圖形符號的工具出現(xiàn)。容易使用設計符號的工具必須在希望人們使用這種方法之前就有了。把這種觀點與在軟件設計過程中要求文檔這一事實結合,可以看[1。事實上,每個公司都有了這些工具(所以試用這種方法不需要花費這符合++的精神,我們是建立在已有的知識和工具基礎上的,而不是把它們丟掉。[2],但它不能緊密地支持集體討論。但是,每個人都懂得畫輪廓,而且很多字處理器有一些畫輪廓人們可以擴展和推倒輪廓,決定于系統(tǒng)中粒度的不同層次。(如后描述)因為程序員創(chuàng)建了設高概建立的系統(tǒng),無論如何復雜,都有一個基本的目的,它服務于哪一行業(yè)和它應滿足什以基本需要。如果我們看看用戶界面、硬件、系統(tǒng)特殊的細節(jié)、編碼算法和效率問題,那么我們最終會發(fā)現(xiàn)它有簡單和直的。就像好塢中謂的高概念,我們能用兩句話描述它這種純描述是起點。高概念相當重要,因為它為我們的項目定調。它是委派語句,不需要一開始就正確(可以在完全清楚它之前完善這個論述或構思設計,它只是嘗試,直到它正確。例如,在空通控制系統(tǒng)中,我們可以從系統(tǒng)的一個高概念開始,即準備建立“控制塔飛機?!钡钱攲⒃撓到y(tǒng)用于非常小的飛機場時,也許只有一個導航員或無人導航。更有用的模型不會使得正在論述劇本的論述是用一兩頁紙寫的故事概要,即高概念的外層。計算機系統(tǒng)發(fā)展高概念和論述的最好的途徑可能是組成一個小組,該小組有一個具有寫能力的輔助工具。在集體討論中能提出建議,輔助工具在與小組相連的網絡計算機上或在屏幕上表達這些思想。輔助工具只起捉刀人的作用,不評價這些思想,只是簡單地使它們清楚和保持它們通順。論述變成了初始對象發(fā)現(xiàn)的起點和設計的第一個雛形,它也能在擁有輔助工具的小組內完成。結構對于系統(tǒng),結構是關鍵。沒有結構就會任意收集意義。有了結構,就有了故事。我的觀察是基于我最熟悉的 Word的擴展功能,它已被用于產生了這本書的照相機準備的頁我鼓勵這種選擇,即用簡單的方框、線和符號,它們在畫字處理的包時是可用的,而不是很難產生的無定型的形狀。論述包括名詞和動詞。當我們列出它們后,一般將名詞作為類,動詞或者變?yōu)檫@些類的方這是一個反復的過程。在將來的階段和后面的設計中可以增加另外的類和方法,因為那時程序員對問題會有更清晰的認識。這種構造方法的要點是不需要程序員當前完全理解問題,所以不期望設計一下子展現(xiàn)在程序員的面前。從簡單的論述檢查開始,為每個已找出的唯一名稱創(chuàng)建“對象”中的第二層子段。取那些很顯然作用于對象的動詞,置它們于相詞下面的第三層方法子段。對每個方法增加參數表如果一個類是從另一個類繼承來的,則它的第二層子段應當盡可能靠近地放在這個基類之derived:publicbase時應當做的。這允許雖然能設置系統(tǒng)去表示從公共接口繼承來的方法,但目的是只創(chuàng)建類和它們的公共接口,其他元素都被認為是下面實現(xiàn)的部分,不是設計。如果要表示它們,它們應當作為相應類下面的文本層注解出現(xiàn)。OccamsRazor辦法:考慮這個選擇并選擇最簡單的一個,因為簡單的類幾乎總是最好的。向類增加元素很容易,但是隨著時間的推移,丟掉元素就困難了。如果需要培植這一過程,請看一個懶程序員的觀點:您應當希望哪些對象魔術般地出現(xiàn),用以解決您的問題?讓一些可以用的類和各種系統(tǒng)設計模式作為手頭的參考是有用的。我們不要總是在對象段里,分析這個論述時應當在對象和系統(tǒng)設計之間來回運動。任何時候,我們都可能想在任子段下面寫一些通文本,關特殊類或方法的想或注解。從高概念和論述開始,會出現(xiàn)一些子情節(jié)。通常,它們就像“輸入、過程、輸出”或“用戶界面、活動”一樣簡單。在“設計”下面,每個子情節(jié)有它自己的第二層子段。大多數故事沿用一組公共情節(jié)。在oopoop設計模式上的資源,可以幫助對情節(jié)的搜索。我們現(xiàn)在正在創(chuàng)建系統(tǒng)的粗略草圖。在集體討論會上,小組中的人們對他們認為應該出現(xiàn)在系統(tǒng)中的活動提出建議,并且分別記錄,不需要為將它與整個系統(tǒng)相連而工作。讓整個項目組,包括機械設計人員(如果需要、市場人員、管理人員,都。這是特別重要的,這不僅使得每個人心情舒暢,因為他們的意見已經被考慮,而且每一個人的參加對會議都是有價值的。在特殊的子情節(jié)下面,每個階段都給出它自己的第三層子段。條件和過渡被描寫為文本,放在這個階段的標題下。情況如果理想,我們最終能夠寫出每個子情節(jié)的基本的東西(因為設計是反復過程,作為對象的創(chuàng)建并向它們發(fā)送的消息。這就變成了這個子情節(jié)的最初代碼。開這是粗設計到編譯代碼的最初轉換,編譯代碼能被測試,特別是,它將證明或者反證我們該轉換用這樣法,即通過對代碼中的結構或有關文字的改變重新產生文檔。這樣,在編碼開始后(和不可避免的改變出現(xiàn)后)產生設計文檔就變得非常容易了,而設計文檔能變成項目進展的報告工具。通過在第一層的標題中使用標準段名“對象”和“設計”,我們就能運行我們的工具以突出這些段,并由它們產生文件頭。依據我們所在的主段和正在工作的子段層,完成不同的工作。最容易的辦法可能是讓我們的工具或宏把文檔分成小塊并且相應地在每一小塊上工作。對于“對象”中的每個第二層段,在段名(類名和它的基類名,如果有的話)中會有足夠的信息用以自動地產生類,在這個類名下面的每個第三層子段,段名(成員函數名、參數表和返回類型)中會有足夠的信息用以產生這個成員函數的。我們的工具將簡單地管理這些并創(chuàng)建類。為了使問題簡單,單個類將出現(xiàn)在每個頭文件中。命名這些頭文件的最好辦法,也許編制情節(jié)可以更精細。每個子情節(jié)可以產生一個獨立的函數,由內部main()調用,或者就是main()中的一段。從一個能完成我們的工作的事情開始,更好的模式可能在以后的反復中形為“對象”段中描述的每個類產生一個頭文件,也就是為每一個類創(chuàng)建一個類,帶有公共接口函數和與它們相聯(lián)系的描述塊;對每個類附上在以后很容易分析的專門標號。//#[1]、//#[2]等等。所有產生的文件都有文檔注釋,放在帶有標號的專門標識塊中。類名和函數也保留注釋標記。這樣,轉換工具能檢查、提取所有信息,并用文檔描述語言更好地重新產生源文檔,例如用RichTextFormat(RTF)描述語言。在這個階段,有兩件事會發(fā)生。如果設計是在早期,那么我們可能需要繼續(xù)加工處理集體討論會的文檔(而不是代碼)或小組負責的那部分文檔。然而,如果設計是完全充足的,那么我們就可以開始編碼。如果在編碼階段增加接口元素,則這些元素必須連同加過標號的注釋一起由程序員加標號,所以重新產生的程序能用新信息產生文檔。如果我們擁有前端編譯器,我們確實可以對類和函數自動進行編譯,但是它是大作業(yè),并且這個語言正在演化。使用明確的標號,是相當不安全的,商業(yè)瀏覽工具能用以檢驗是否所有的公共函數都已經形成文檔了(也就是,它們已加標號了。重這類似于重寫劇本以完善它,使它更好。在程序設計中,這是重復過程,我們的程序從好到更好,在第一遍中還沒有真正理解的問題變得清楚了。我們的類從在單個項目中使用進化為可重用的資源。從工具的觀點看,轉換該過程略微復雜,我們希望能分解頭文件,使我們能重新整理這些文件使它們成為設計文檔,包括在編碼過程中已經做過的全部改變。在設計文檔中對設計有任何改變,頭文件也必須完全重建,這樣就不會丟失為了得到在第一遍反復中編譯所需要的頭文件而做的任何工作。因此,我們的工具不僅應當能找出加標號的信息,將它們變成段層和文本#include。我們應當記住,頭文件表達了類設計而須能夠由設計文檔重新產生頭文件。我們還應當注意文本層注解和討論,它們最初產生時被轉換為加標號的注釋,比在設計演化過程中程序員修改的內容。基本上,這些注解和討論被收集并放在各自的地方,因此設計文檔反映了新的信息。這就允許我們去改變這些信息,并且返還到已產生的頭文件中。對于系統(tǒng)設計(main()和任何支持函數,我們也可能想獲得整個文件,添加段標識符,例如A、B、C等等,作為加標號的注釋(不用行號,因為行號會改變,并附上段描述(然后返還main()文件,作為加標號的文本。須知道什么時候停止,什么時候重復設計。理想的情況是,我們達到了目標功能,處在完善和增加新功能的過程中,最后期限到來,強迫我們停止并發(fā)出我們的版本(記住,軟。邏我們會周期性地希望知道項目在什么地方需要重新整理文檔。如果是在網上使用自動化工具,這個過程無關緊要。經常地整集和設計文檔是項目者或管理者的責任,而項目組或個人只對文檔的一小部分負責(也就是他們的代碼和注釋。在任何時候,都可以通過簡單地“刷新”文檔生成當前的報告。這樣可以看到程序各部分的情況,也支援了項目組,并為最終用戶文檔提供了直接的更新。這些文檔對于使新組員盡快參加工作也很有價值。單個文檔比由某些分析、設計方法而產生的所有文檔更合理。雖然一個較小的文檔當前有大量的形式化方法(不下20種)可用,由程序員選擇[1]。有一些并不完全獨立,它們有共同的思想基礎,在某個更上,它們都是相同的。在最低層,很多方法都受語言的缺省表現(xiàn)約束,所以每個方法大概只能滿足簡單的項目。真正的好處是在較上,一個方法可用于實時硬件控制器,但可能不容易適合數據庫的設計。[1]這些是下綜述:Object ysisandDesign:DescriptionofMethods,editedbyAndrewT.F.HuttofObjectManagementGroup(OMG),johnWiley&Sons,1994。以此來認識一個方法是否適合我們的特殊風格,或者我們是否真需要一個方法。下面是對最流行的三種方法的描述,主要是供參考,不是比較。如果讀者想了解的方法,有許多書Booch方法[1]是最早、最基本和最廣泛被的一個方法。因為它是較早發(fā)展的,所以對各這是可預見的一小步。我們用自然語言問題和解,并且確定關鍵特性,例如形成類的基本名詞。如果我們在行業(yè),可能想確定工人、鞭、顧客,進而,可能需要確定化學藥劑師、組裝者、處理者,業(yè)余鞭者和專業(yè)鞭者、者和觀眾。甚至更專門的,能確這是在相應的抽象層上定義類。如果我們計劃創(chuàng)建一個類,我們應當確定類的相應觀眾。例如,如果創(chuàng)建鞭類,那么誰將觀察它,化學藥劑師還是觀眾?前者想知道在結構中有什么化學藥劑,而后者將對鞭時釋放的顏色和形狀感。如果化學藥劑師問起一個鞭產生主顏色的化學藥劑,最好不要回答“有點冷綠和紅”。同樣,觀眾會對鞭點火后噴出的只是化學方程式感到迷惑不解。也許,我們的程序是為了眼前的市場,化學藥劑師和觀眾都會用它,在這種情況下,鞭應當有屬性客體屬性并且能以和觀察者相應外觀出現(xiàn)。確定它們之間的關系(CRC卡片(Class,Responsibility,Collaboration,CRC)卡片。這是一種小卡片(通常是一個索引卡,在它上面寫上這個類的狀態(tài)變量、它的責任也就是它發(fā)送和接受的消息)和對與它互相作用的其他類的。為什么需要索引卡片?理由是我們應當能在一張小卡片上存放我們需要知道的關于一個類的所有內容,如果不能滿足這點,那么這個類就太復雜了。理想的類應一種不涉及主要技術的解決辦法對于每個人都可用的(就像本章前面描述的草稿方法中的文檔結構化一樣。這樣的設計過程給人一種類似著名的程序開發(fā)瀑布流方法的感覺?,F(xiàn)在對這種方法的看法是有的。在第一遍查看主要的抽象是否可以將類清晰地分離之后,可能需要重復前三個步驟。Booch寫了一個“粗糙旅程完型設計過程”。如果這些類真正反映了這個解的自然語言描述,那么程序有完型的觀點應當是可能的。也許要記住的最重要的事情是,通過缺省—實際上是通過定義,如果修改了一個類,它的超類和子類應當仍然工作。不需要害怕修改,它不會/或被改變的這個類的特定協(xié)作者中。為了這個類而對C[1]參看Object-OrientedDesignwithApplicationsbyGradyBooch,BenjaminCummings,1991.有關C++更新的版責任驅動的設計這個方法[1]也用CRC卡片。在這里,正如名稱蘊涵,卡片的重點在于責任的,而不是外觀。這可由下面例子說明Booch方法可以產生雇員—銀行雇員—銀行經理的繼承,而更形式化地說,RDD包含如下數據或狀態(tài) 對每個類的數據或狀態(tài)變量的描述池和源 數據池和源的標識;處理或產生數據的類觀察者或觀點 觀點或觀察者類,用以硬件依賴對象建模技術對象建模技術[2](OMT)Booch方法強調類的功能表現(xiàn),簡單地定義它們作為自然語言解的輪廓。RDD進了一步,強調類的責任超過強調類的表現(xiàn)。Booch方法和RDD產生的那些模功能模型,“如何”,數據流程表:該功能模型數據流。它的理論是,在程序的最如果我們決定采用OOP伙伴開始使用OOP?”想,作為獨立的程序員,應當如何學習使用新語言和新程序設計。正如我們以前所做的,首先訓練和做例子,再通過一個試驗項目得到一個基本的感覺,不要做太的事情,然后嘗試做一個“真實世界”的實際有用的項目。在我們的第一個項目中,我們通過讀、向上司問問題、與朋友切磋等方式,繼續(xù)我們的訓練。基本上,這就是許多作者建議的從C轉到C++的方法。轉變整個公司當然應當采用某個動態(tài)的小組,但回憶個人是如何做逐步進入當向OOP和C++轉變時,有一些方針要C代碼上的投資,并且當每個人都在為這些參看DesigningObject-OrientedSoftwarebyRebeccaWirfs-Brocketal.,PrenticeHall,1990參看Object-OrientedModelingandDesignbyJamesRumbaughetal.,PrenticeHall,1991有時建議采用另法,即在整個公司層一起訓練,包括為策略管理員而開設的概論課程,以及為項目建設者而開設的設計課程和編程課程。對于較小的公司或較大公司的部門,用他們做事情的方法去做基本的改變是非常好的。然而代價較高,所以一些公司可能選擇以項目層訓練開始,做式的項目(可能請一個外面的導師,然后讓這個項目變成公司他首先嘗試一個低風險項目,并允許出錯。一旦我們已經得到了一些經驗,我們就將這第一OOP的技術支柱。第一個項目可能不能正確工作,所以該項目在事情的安排上應當不是非常重要的。它應當是簡單的、自包含++以適合我們自己的需要。這是設計模式[1]的一般概念。轉變?yōu)?+的主要經濟動機是容易使用以類庫形式存在的代碼,最短的應用開發(fā)周期是除了main()以外不必自己寫任何東西。然而,一些新程序員不理解這個,不知道已存在的類庫,或由于對語言的迷戀希望寫可能已經存在的類。如果我們努力查找和重用其他人在轉變過程中的早期代碼,那么我們在OOP和C++雖然用C++編譯C代碼通常會有(有時是很大的)好處,它能發(fā)現(xiàn)老代碼中的問題,但是把時間花在對已存在的功能代碼進行C++重寫上,通常不是時間的最佳利用。如果代碼是為重用而編寫的,會有很大的好處。但是,有可能出現(xiàn)這種情況:在最初的幾個項目中,并不能看++和OOP好。管理對于管理員,他的任務就是為他的組獲得資源,他的小組克服通往成功的。并且,他應當努力創(chuàng)造高產的和令人愉快的環(huán)境,以使得他的小組最大可能完成他所要求的奇跡。轉變到++的過程包含有下面的三類,如果不花費何代價,那真是奇怪的。雖然對于C程序員(也許對于其他過程語言的程序員)C++比選擇其他OOP語言代價++些。這個代價要比得到C++編譯器大得多。如果投資培訓(也許為了指導第一個項目,并且如果選購解決問題的類庫,而不是試圖自己建立這些類庫,那么可以將中長期代價減到最低。這些都是很花錢的,必須在制定計劃時充分考慮。另外,當學習新語言連同程序設計環(huán)境時,[1]參看 etal.,出處同上還會有損失效率的隱含代價。培訓和指導確實能使這些代價降到最低,但是組員們必須克服他們自己的困惑去理解這些問題。在這個過程中,他們將會犯的錯誤(這是一個特征,因為失敗是成功之母)和有更低的效率。盡管如此,對于一些類型的程序設計問題、正確的類和正確的開發(fā)環(huán)境,即使我們還在學習++,也可能比我們仍然用C語言時有更高的效率(即便考慮到我們正在犯的錯誤和每天寫更少行的代碼。OOP統(tǒng)的OOPC++是在已有生產程序的情況下設計的。當我們的焦點是建立快速原型時,我們可以盡快地把構件拉在一起,而忽略效率問題。如果我們正在使用任何第庫,這些庫通常已經被廠商優(yōu)化過了,我們用快速這就行了。如果達不到這種要求,我們就開始用一個有益的工具進行調整,首先尋求加速,這可以通過簡單地運用建立在C++所以使用特定類的原有代碼不需要改變。只有這一切都無法解決這個問題時才需要改變設計。性能在設計中的地位如此重要,以致于這一因素必然是主要設計標準的指標之一。通過快速原型較早地發(fā)現(xiàn)這一點是有好處的。C和C++1%實際上我們可以用C得到在規(guī)模和速度上超過C的系統(tǒng),因為我們?yōu)?+當項目組開始使用OOP和C++時,程序員們將會出現(xiàn)一系列普遍的設計錯誤。這經常會發(fā)生,因為在早期項目的設計過程中從專家們那里得到的反饋太少,公司中沒有專家。程序員似乎會覺得,在這個周期中,他懂得OOP太早了并開始了一條不好的道路。有時,對這個語言有經驗的人認為顯而易見的事情可能是新手們在內部激烈爭論的。大量的這類問題都這一章希望讀者對面向對象程序設計和C++的廣泛問題有一定的感性認識,包括為什么OOP和C++C++是否能很好地C++滿足,那么可以用它研究替代物。即便他最終選擇了C++作為他的語言,他至少應當懂得這些選項是什么,并應當對為什么取這個方向有清晰的看法。第2 數據抽C++是一個能提高效率的工具。為什么我們還要努力(這是努力,不管我們試圖做的轉變多么容易)使我們從已經熟悉且效率高的語言(在這里是語言)轉到另一種新的語言上?而且使用這種新語言,我們會在確實掌握它之前的一段時間內降低效率。這歸因于我們確信通過使用新工具將會得到更大的好處。用程序設計術語,多產意味著用較少的人在較少的時間內完成更復雜和更重要的程序。然(簡單地講,提高生產效率,意味著本應花費三個人一星期的程序,現(xiàn)在只需要花費一個人一兩天的時間。這會涉及到經濟學的多層次問題。生產效率提高了,我們很高興,因為我們正在建造的東西功能將會更強;我們的客戶(或)很高興,因為產品生產又快,用人又少;我們的顧客很高興,因為他們得到的產品更便宜。而極大提高效率的唯一辦法是使用其他人的代碼,即使用庫。庫,簡單地說就是一些人已經寫的代碼,按某種方式包裝在一起。通常,最小的包是帶有擴展名如LIB的文件和向編譯器庫中有什么的一個或多個頭文件。連接器知道如何在LIB文件中搜索和提取相應的已編譯的代碼。但是,這只是提供庫的法。在多種體系結構的平臺上,例如UNIX,通常,提供庫的最明智的方法是用源代碼,這樣在新的目標機上它能被重新編譯。而在微軟indows上,動態(tài)連接庫是最明智的方法,這使得我們能夠利用新發(fā)布的DDL經常修改我們的程序,我們的庫函數銷售商可能已經將新DDL所以,庫大概是改進效率的最重要的方法。C++的主要設計目標之一是使庫容易使用。這意味著,在C中使用庫有。懂得這一點就對C++設計有了初步的了解,從而對如何使用它 首先,必須知道“”和“定義”之間的區(qū)別,因為這兩個術語在全書中會被確切地使空空間。對于變量,編譯器確定這個變量占多少單元,并在內存中產生存放它們的空間。對于函數,編譯器產生代碼,并為之分配空間。函數的空間中有一個由使用不帶參數表或帶地址操作符的函數名產生的指針。定義也可以是。如果該編譯器還沒有看到過名字A,程序員定義intA,則編譯器馬上常常使用于extern關鍵字。如果我們只是變量而不是定義它,則要求使用extern。對于函數,extern是可選的,不帶函數體的函數名連同參數表或返回值,自動地作為一個intf(float,char);是一個函數原型,因為它不僅介紹f這個函數的名字,而且告訴編譯器這個函數有什么樣的參數和返回值,使得編譯C++要求必須寫出函數原型,因為它增加了一個重要的安全層。下面是一些的例子。在函數時,參數名可給出也可不給出。而在定義時,它們是必需的。這在C語言中確全書中,我們會注意到,每個文件的第一行是一個注釋,它以注釋符開始,后面跟冒號。greawk”這樣的文本處理工具從代碼文件中提取信息。在第一行中還包含有文件名,因此能在文本和其他文件中查閱這個文件,本書的代碼磁盤一個袖珍C一個小型庫通常以一組函數開始,但是,已經用過別的C庫的程序員知道,這里通常有更多的東西,有比行為、動作和函數的東西。還有一些特性(顏色、重量、紋理、亮度,它們都由數據表示。在C語言中,當我們處理一組特性時,可以方便地把它們放在一起,形成一個struct。特別是,如果我們想表示我們的問題空間中的多個類似的事情,則可以對每件事情創(chuàng)建這個truct這樣,在大多數C庫中都有一組struct和一組活動在這些struct上的函數?,F(xiàn)在看一個這樣的例子。假設有一個程序設計工具,當創(chuàng)建時它的表現(xiàn)像一個數組,但它的長度能在運行時建立。我稱它為tash。在結構內部需要這結構時可以使用個struct的別名,例如,創(chuàng)建一個鏈表,需要指向下一個truct的指針。在Ctypedef。這樣做使得我們能把struct作為一個新類型處理,并且可以定義這個structstashA,B,注意,這些函數用標準C風格的函數原型,標準C風格比“老”C風格更安全和更storag指針是一個unsignedchar*這是C編譯器支持的最小的片,盡管在某些機器tash被設計用于存放任何類型的變量,所以void*在這里應當更合適。然而,我們的目的并不是把它當作某個未知類型的塊處理,而是作為連續(xù)的字節(jié)塊。OBJ或LIB或DDL等)如下:#include給出。這樣做,可以創(chuàng)建不同于這本書 的另外下initialize完成對structstashstorage指針為零,設置size指示器也為零,表示初始未被分配add()函數在stash的下一個可用位子上插入一個元素。首先,它檢查是否有可用空間,如果沒有,它就用后面介紹的inflate()函數擴展空間。因為編譯器并不知道被存放的特定變量的類型(void*),所以我們不能只做賦值,雖然這的確是很方便的事情。代之,須用標準C庫函數memcpy()一個字節(jié)一個字節(jié)地拷貝這個變量,第一個參數是memcpy()開始拷貝字節(jié)的目的地址,由下面表達式產&(S->storage[S->next*S-它指示從塊開始的第next個可用單元結束。這個數實際上就是已經用過的單元號加一的計數,它必須乘上每個單元擁有的字節(jié)數,產生按字節(jié)計算的偏移量。這不產生地址,而是。器加一,并返回被存值的索引。這樣,程序員可以在后面調用fetch(時用它來取得這個元素。fetch()首先看索引是否越界,如果沒有越界,返回所希望的變量地址,地址的計算采用與對于有經驗的程序員count()乍看上去可能有點奇怪,它好像是自找麻煩,做手工很容易structstash,例假設稱為intStash,那么通過用intStash.next找出它已經有多少個元素的方法似乎更直接,而不是去做count(intStash)函數調用(它有的花費stash的內部表示和計數計算方法,那么這個函數調用接口就允許必要的靈活性。并且,很多程序員不會為找出庫的“更好”的設計而操心。如果他們能著眼于struct和直接取next的值,那么可能不經允許就改變next。是不是能有一些方法使得庫設計者能更好地控制像這樣的問題呢?(是的,這是可預見的。我們不可能預先知道一個stash需要的最大量是多少,所以由torage指向的內存從堆中分配。堆是很大的內存塊,用以在運行時分一些小單元。在我們寫程序時,如果我們還不知道所需內的大,就以使堆。樣,們可直運行時知道要存放200個airne變是20。動內存配函是標準C庫的一部分,包括malloc()、calloc(、realloc()和 ()。inflate()函數使用realloc()為tash得到更大的空間塊。realloc()把已經分配而又希望重分配的單元首地址作為它的第一個參數(如果這個參數為零,例如initialize()剛剛被調用時,realloc()分配一個新塊。第二個參數是這個塊新的長度,如果這個長度比原來的小,這個塊將不需要作拷貝,簡單地告訴堆管理器剩下的空間是空閑的。如果這個長度比原來的大,在堆assert()檢查以確信這個操作成(malloc()、calloc()和realloc())注意,C管器當要它內塊對們用 ()時就回收它們。沒有對堆進行合并的工具,如果能合并就可以提供更大的空閑塊。如果程序多次分配和釋放堆,最終會導致這個堆有大量的空閑塊,但沒有足夠大且連續(xù)的空間能滿足我們對內存分配的需要。但是,如果用堆合并器動內存塊,又會得指針保的不是相應的值。一些作環(huán)境,例如aert()是在ASSE.H中的預處理宏。asert()再調試時,我們可以用一個標志使得這個斷言被忽略。在調試期間,這是非常清楚和簡便的測C程序對一個斷失敗并且出去”在第17,C++是如何用出錯處理來處理重編譯時,如果在棧上創(chuàng)建一個變量那么這個變量單元由編譯器自動開辟和釋放。編譯器準確地知道需要多少容量,根據這個變量的活動范圍知道這個變量的生命期。而對動態(tài)內存分配,編譯器知道需要多少單元,不道它們的生命期,不能動清除。因此用 (), ()告訴堆管理器,這個可以被下一次調用的malloc()、calloc()或realloc()重用。合理的方法是使用庫中cleanup()函數,因為在這里,該函數做所有類似的事情。在main()的開頭定義了一些變量,其中包括兩個stash結構變量,當然。稍后須在這個程序塊的對它們初始化。庫的問題之一是須向用戶認真地說明初始化和清除函數的重要性,如果這些函數未被調用,就會出現(xiàn)許多問題。遺憾的是,用戶不總是記得初始化和清除是必須的。他們只知道他們想完成什么,并不關心我們反復說的:“喂,等一等,您必須首先發(fā)生(只有多預示。intStash適合于整型,stringStash適合于字符串。這些字符串是通過打開源代碼文件LIBTEST.C和把這些行讀到stringStash而產生的。注意一些有趣的地方:標準C庫函數打開和讀文件所使用的技術與在stash中使用的技術類似。fopen()返回一個指向FILEstruct的指針,這個FILEstruct是在堆上創(chuàng)建的,并且能將這個指針傳給涉及到這個文件的任何函數。(在這里是fgets()。fclose()所做的事情之一是向堆釋放這個FILEstruct。一旦我們開始注意到這種模式的,包含著struct和有關函數的C庫后,我們就能到處看到它。裝載了這兩個stash之后,可以打印出它們。intStach的打印用一個for循環(huán),用count()確定它的限度。stringStash的打印用一個while語句,如果fetch()返回零則表示打印越界,這時跳出循C庫創(chuàng)建的問題之前,應當了解另外一些事情(我們可能已經知道這些,C。第一,雖然這里用頭文件,而且實際上用得很好,但它們不是必須的。在C中可能會調用還未的函數。好的編譯器會告誡我們應當首先函數,但不強迫這樣做。這很的,為編器能設以int參數調用的函數有包含int的參數表,并據此處理它,這是很難發(fā)現(xiàn)的錯誤。LIB.Hstash的所有文件中,因為編譯器不可能猜出這個結構是什么樣子的。它能猜出函數,即便它可能不應當這樣,但這是C的一部分。每個獨立的文件就是一個處理單元。就是說,編譯器在每個處理單元上單獨運行,而編譯器在運行時只知道這個單元。這樣,用包含頭文件提供信息是相當重要的,因為它為編譯器提供了對程序其他部分的理解。在頭文件中的特別重要,因為無論是在哪里包含這個頭文件,編器都知道做什。例,若一個文中voidfoo(float),編譯器就知道,如果我們用整型參數調用它,它會自動把int轉變?yōu)閒loa。如果沒有,這個編譯器就會簡單地猜測,有一個函數存在,而不會做這個轉變。對于每個處理單元,編譯器創(chuàng)建一個目標文件,帶有擴展名.o或.bj或類似的名字。必須再用連接器將這些目標文件連同必要的啟動代碼連接成可執(zhí)行程序。在連接期間,所有的外部必須定。如在LIBTESC中并用數initialize()和fetch(),(也是,編譯器知它們像什么,)在LIB.C中定義的,在LIBTES.C中這些調用都是外部。連接器將目標文連接在一時,它找出未確定的并尋找這些引要識在C中,就是函數名,通常在它們前面加上下劃線。所以,連接器所要做的就是讓被調用的函數名與在目標文件中的函數體匹配起來。如果我們偶然做了一個調用,編譯器解釋為foo(int),而在其他目標文件中有foo(float)的函數體,連接器將認為一個_fo在一處而另一個_foo在另一處,它會認為這都是對的。在調用foo()處將一個int而foo()float。如果這個函數只讀這個值而不對它寫,尚不會破壞這個棧。但從這個棧中讀出的float值可能會有另外的某種理解。這是的情況,因為很分別編譯時(把代碼分成多個處理單元,我們需要一些方法去編譯所有的代碼,并告訴連接器把它們與相應的庫和啟動代碼放在一起,形成一個可執(zhí)行文件。大部分編譯器允許用一條命令行語句。例如編譯器命名為cpp,可寫:cpplibtest.c這個方法帶來的問題是,編譯器必須首先編譯每個處理單元,而不管這個單元是否需要重建。雖然我們只改變了一個文件,但卻需要耗費時間來對項目中的每一個文件進行重新編譯。UNIX(C的誕生地)提出,是一個被稱為make的程序。make比較源代碼文件的日期和目標文件的日期,如果目標文件的日期比源代碼文件的早,ake這器元理可譯檔1]中學到的關于maemaemakefile有點乏味。makefile是描述項目中所有文件之間關系的文本文件因此,編譯銷售商們自的項目創(chuàng)建工具這些工具向們詢問項目中有哪些處理單元,并確定它們的關系。這些關系有些類似于makefil文件,通常稱為項目文件。程序設計境這個件,所以我不必它擔心。項目文的配置和使隨系統(tǒng)而文檔(雖然由編譯器銷售商提供的項目文件工具通常是非常簡單的,可以不費勁地學會它們。應注的一問文命。在中,慣例是以擴展名.命名文件包含),以.c(C繼續(xù)演化。它首先是在ix.H和.C-SC.hxx和.cx還是cp.。stashC程序[1]參看由作者編寫的C++Inside&Out,(Osborne/McGraw-Hill,1993)須向這個庫中的每一個函數傳遞這個結構的地址。而當讀這些代碼時,這種庫機制會和函數調用的含義相,試圖理解這些代碼時也會引起。然而在C中,使用庫的最大的是名字問題。C對于函數使用單個名字空間,所以現(xiàn)在假設要支持從不同的廠商的兩個庫,并且每個庫都有一個必須被初始化和清除的結構。兩個廠商都認為initialize()和cleanup()是好名字。如果在某個處理單元中同時包含了這,C編器呢,準C給一個出錯,告訴在函數的兩個不同的參數表中類型不匹配。即便不把它們包含在同一個處理單元中,連接器也會有問題。好的連接器會發(fā)現(xiàn)這里有名字,但有些編譯器僅僅通過查找目標文件表,按照在連接表中給出的次序,取第一個找到的函數名(實際上,這可以看作是一種功能,因為可以用自己的版本替換一個庫函數。C庫廠商常常會在它們的所有函數名前加上一個獨特字符串。所以,initialize()和cleanup()可能變?yōu)閟tash_initialize()和stash_cleanup()。這是合乎邏輯的,因為它“分解了”這個struct的名字,++rut突。而當一些函數在特定struct上運算時,為什么不把這一優(yōu)點擴展到這些函數名上呢?也就truct首先注意到的可能是新的注釋文法CC原來的注釋文法仍然能用。C++注釋直到該行的結尾,它有時非常方便。另外,我們會在這本書中,在文件的第一行的//之后加一個冒號,后面跟的是這個文件名和簡要描述。這就可以了解代碼所在的文件。構名轉變?yōu)檫@個程序的新類型名(就像int、char、float、double一樣。stash的用法仍然相同。所有的數據成員與以前完全相同,但現(xiàn)在這些函數在struct的內部了。另外,注意到,對C版本中第一個參數已經去掉了。在C++在這個結構上運算的所有函數的一個參數,而是編譯器背地里做了這件事。現(xiàn)在,這些函數僅有的參數與這些函數所做的事情有關,而不與這些函數運算的機制有關。C庫中的那些同樣有效,是很重要的。參數的個數是相同的(即stashA,B,)被產生的代碼幾乎和我們已經為C庫寫的一樣。有趣的是,這同時就包括了為過程stah_initialize()、stah_cleanup()tuttahinitialize()initialize()相抵觸。大部分時間都不必為函數名字分解而擔心—即使使用未分解的函數名。但有時還必須能夠這個initialize()個structtash
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 砌體工程勞務合同模板
- 復印機租賃協(xié)議模板
- 項目并購協(xié)議
- 無形資產買賣協(xié)議
- 政府采購抵押權服務合同
- 股票配資技巧傳授合同
- 新時代大學生綜合素養(yǎng)與發(fā)展
- 股票配資賬戶風險控制輿情知識普及協(xié)議
- 綜合性遠程辦公設備租賃協(xié)議模板
- 耐低溫墻體砌筑協(xié)議
- 2023年社區(qū)換屆選舉會議記錄【三篇】
- 2023年黑龍江省哈爾濱市紀監(jiān)委遴選面試題及參考答案
- 好書推薦讀書分享名著導讀童年PPT
- 海康威視DSK1T系列接鎖電源操作手冊
- 鐵路基礎知識考試題庫500題(單選、多選、判斷)
- 多媒體會議室維護維保方案書
- 【失敗案例】“瘋太陽”鄭州亞細亞集團的隕落亞細亞(戰(zhàn)略和體制)
- 第一次全國水利普查技術細則
- 安全主題班會課件 法制宣傳主題班會
- 大學化學-物質結構基礎
- 醫(yī)院印章使用申請表
評論
0/150
提交評論