乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      effective C++ 導(dǎo)讀

       社交力學(xué) 2011-12-25

      導(dǎo)讀

      學(xué)會一個程式語言,是一回事兒;學(xué)會如何以此語言設(shè)計並實作出有效的程式,又是一回事兒。C++ 尤其如此,因為它很不尋常地涵蓋了罕見的威力和豐富的表現(xiàn)力,不但建立在一個全功能的傳統(tǒng)語言(C)之上,更提供極為廣泛的物件導(dǎo)向(object-oriented)性質(zhì),以及對templates 和exceptions(異常狀態(tài))的支援。

      假以適當(dāng)運用,C++ 是個可以讓你感受愉悅的夥伴。各種不同的設(shè)計方式,包括物件導(dǎo)向型式和傳統(tǒng)型式,都可以直接在這個語言中表現(xiàn)並有效地實作出來。你可以定義新的資料型別,它們和語言內(nèi)建的型別表面上無分軒輊,實質(zhì)上則更具彈性。明智地選用一些謹(jǐn)慎設(shè)計的classes — 自動完成記憶體管理、別名(aliasing)處理、初始化動作與清理動作、型別轉(zhuǎn)換、以及軟體開發(fā)的其他難題與禍根— 可以使程式設(shè)計更容易,更直觀,更有效,更少錯誤。是的,要寫出有效的C++ 程式並不會太困難,如果你知道怎麼做的話。

      如果沒有什麼訓(xùn)練與素養(yǎng),就冒然使用C++,會導(dǎo)至做出來的碼不易理解、不易維護、不易擴充、缺乏效率、而且容易出錯。

      關(guān)鍵在於找出C++ 可能絆倒你的狀況有哪些,然後學(xué)習(xí)如何避開它們。這正是本書的目的。我假設(shè)你已經(jīng)認(rèn)識C++ 並對它有某種程度的使用經(jīng)驗。我提供一些準(zhǔn)則,讓你更有效地使用這個語言,使你的軟體容易理解、容易維護、容易擴充、效率高、而且行為如所預(yù)期。

      我提出的忠告分為兩大類:一般性的設(shè)計策略,以及特殊的(比較難得一見的)語言性質(zhì)。

      設(shè)計方面的討論集中在如何對不同的方法(俾得以C++ 達成某個目標(biāo))做取捨。如何在inheritance(繼承)和templates(範(fàn)本)之間做選擇?在templates 和generic pointers(泛型指標(biāo))之間?在public inheritance(公開繼承)和private inheritance (私有繼承)之間?在private inheritance 和layering(分層技術(shù))之間?在function overloading(函式多載化)和parameter defaulting(參數(shù)預(yù)設(shè)值)之間?在virtual function(虛擬函式)和nonvirtual functions(非虛擬函式)之間?在pass-by-value (傳值)和pass-by-reference(傳址)之間?一開始就做出正確的決定是很重要的,因為不正確的選擇或許不會一下子就浮現(xiàn)影響,但是在開發(fā)過程的後期,矯正它往往很困難、很花時間,很混亂,很令人沮喪,事倍功半,成本很高。

      在你確切知道你要做什麼之後,把它做對,恐怕也不是件太容易的事。什麼是 assignment 運算子的適當(dāng)傳回型別?當(dāng)operator new 無法找出足夠的記憶體,它該有怎樣的行為?destructor 何時應(yīng)該被宣告為virtual?你應(yīng)該寫一個member initialization list(成員初值列)嗎?在如斯細節(jié)中努力,也頗具有決定性,因為如果不這樣,常會導(dǎo)至意料之外或神秘難解的程式行為。更糟的是這類脫軌行為可能不會立即浮現(xiàn),這些恐怖的碼或能通過品管檢驗,卻仍然藏匿著許多未偵測出來的臭蟲— 不定時炸彈正等待引爆。

      這不是本得一頁頁讀下去才有感覺的書籍。你甚至不需要依序讀它。所有素材被我分為50 個條款,每一個都相當(dāng)獨立。不過條款之間會彼此參考,所以閱讀本書的一種方法是先從感興趣的條款開始,然後遵循其參考指示,進一步讀下去。

      所有條款被我分為七大類。如果你對某類主題特別感興趣,例如「記憶體管理」或「物件導(dǎo)向設(shè)計」,可以從相關(guān)章節(jié)開始,一路讀下去,或是跳躍前進。不過最後你會發(fā)現(xiàn),本書的所有內(nèi)容對於高實效的C++ 程式設(shè)計而言,都十分基礎(chǔ)而重要,所以幾乎每個條款最後都會和其他條款互有牽連。

      這並不是一本C++ 參考工具書,也不是一本讓你從頭學(xué)習(xí)C++ 的書。例如,雖然我熱切告訴你一些有關(guān)「撰寫自己的operator new」的注意事項(條款7~10),但是我假設(shè)你可以從其他地方獲知,operator new 必須傳回一個void*,其第一引數(shù)的型別必須是size_t。許多C++ 語言書可以帶給你這樣的資訊。

      這本書的目的是要強調(diào)那些其他書籍往往淺淺帶過(如果有的話)的C++ 程式設(shè)計概念。其他書籍描述的是C++ 語言的各個成份,本書則告訴你如何將那些成份組合起來,完成一個有效的程式。其他書籍告訴你如何讓程式順利編譯,本書則告訴你如何避開編譯器不會告訴你的一些問題。

      和大部份語言一樣,C++ 有著豐富的「傳統(tǒng)」,在程式員之間口耳相傳,形成這個語言的偉大傳承的一部份。我企圖在這本書中以容易閱讀的型式記錄一些長久累積而來的智慧。

      然而在此同時,我必須告訴你,本書僅限於正統(tǒng)的、可移植的C++ 語言。只有明列於ISO/ANSI 標(biāo)準(zhǔn)(見條款M35)中的性質(zhì),才會被本書採用。本書之中,移植性是個關(guān)鍵考量。如果你想要尋找因編譯器而異的特殊技法,本書不適合你。

      但是,啊呀,標(biāo)準(zhǔn)規(guī)格所描述的C++,與社區(qū)軟體商店所賣的編譯器(s) 的表現(xiàn),多少有點出入。所以當(dāng)我指出某個新的語言特性頗有用處時,我也會告訴你如何在缺乏那些特性的情況下產(chǎn)出有效的軟體。畢竟在確知未來即將如何如何之際,卻忽略那些美麗遠景而儘做些低下的勞力工作,容我坦言是相當(dāng)愚蠢的;但是反過來看,你也不能在最新最偉大的C++ 編譯器(s) 降臨世界之前,空自等待而束手無策呀。你必須和你手上可用的工具一起打拼,而本書正打算幫助你這麼做。

      注意我說編譯器(s) — 複數(shù)。不同的編譯器對標(biāo)準(zhǔn)C++ 的滿足程度各不相同,所以我鼓勵你至少以兩種編譯器(s) 來開發(fā)程式。這麼做可以幫助你避免不經(jīng)意仰賴某個編譯器專屬的語言延伸性質(zhì),或是誤用某個編譯器對標(biāo)準(zhǔn)規(guī)格的錯誤闡示。這也可以幫助你避免使用過度先進的編譯器特殊技術(shù),例如獨家廠商才做得出來的某種語言新特性。如此特性往往實作不夠精良(臭蟲多,要不就是表現(xiàn)遲緩,或兩者兼具),而且C++ 社群往往對這些特性缺乏使用經(jīng)驗,無法給你應(yīng)用上的忠告。雷霆萬鈞之勢固然令人興奮,但當(dāng)你的目標(biāo)是要產(chǎn)出可靠的碼,恐怕還是步步為營(並且能夠與人合作)得好。

      你在本書中找不到C++ 的必殺秘笈,也看不到通往C++ 完美軟體的唯一真理。 50 個條款中的每一個帶給你的都只是準(zhǔn)則,包括如何完成較好的設(shè)計,如何避免常見的問題,如何到達更好的效率,但任何條款都不可能放之四海皆準(zhǔn)。軟體的定義和實作是極為複雜的工作,常會受到硬體、作業(yè)系統(tǒng)、以及應(yīng)用軟體的束縛,所以我能夠做的最好事情就是提供一些準(zhǔn)則,讓你可以依循產(chǎn)生出比較好的程式。

      如果任何時候你都奉行每一個條款,應(yīng)該不太可能掉進最常見的一些C++ 陷阱。不過準(zhǔn)則畢竟只是準(zhǔn)則,可能存在例外情況。那正是為什麼每個條款都帶有一堆解釋的原因。這些解釋是本書最重要的資產(chǎn)。唯有徹底瞭解一個條款背後的基本原理,你才能合理決定此條款是否適用於手上的專案,或你正艱苦奮鬥的難題上。

      本書的最佳用途,就是增進你對C++ 行為的瞭解,知道它為什麼有那樣的表現(xiàn),以及如何將其行為轉(zhuǎn)化為你的利益。盲目運用本書所列的條款並不適當(dāng),不過話說回來,你或許不應(yīng)該在缺乏好理由的情況任意違反任何一個條款。

      這樣性質(zhì)的書籍中,專用術(shù)語的解釋並非重點所在。那樣的工作頂好是留給語言界的「律師」去做。然而有少量C++ 辭彙是每個人都應(yīng)該要懂的。以下術(shù)語一再出現(xiàn),所以有必要確定你我之間對它們有共同的認(rèn)知。

      所謂宣告(declaration),用來將一個object、function、class 或template 的型別名稱告訴編譯器。宣告式並不帶有細目資訊。下面統(tǒng)統(tǒng)都是宣告:

      extern int x; // object declaration
      int numDigits(int number); // function declaration
      class Clock; // class declaration
      template
      class SmartPointer; // template declaration

      所謂定義(definition),用來將細目資訊提供給編譯器。對object 而言,其定義式是編譯器為它配置記憶體的地點。對function 或function template 而言,其定義式提供函式本體(function body)。對class 或class template 而言,其定義式必須列出該class 或template 的所有members:

      int x; // 這是物件的定義式
      int numDigits(int number) // 這是函式的定義式
      { // 此函式傳回其參數(shù)的數(shù)位(digits)個數(shù)
      int digitsSoFar = 1;
      if (number < 0) {
      number = -number;
      ++digitsSoFar;
      }
      while (number /= 10) ++digitsSoFar;
      return digitsSoFar;
      }
      class Clock { // 這是class 的定義式
      public:
      Clock();
      ~Clock();
      int hour() const;
      int minute() const;
      int second() const;
      ...
      };
      template
      class SmartPointer { // 這是template 的定義式
      public:
      SmartPointer(T *p = 0);
      ~SmartPointer();
      T * operator->() const;
      T& operator*() const;
      ...
      };
      
      上述程式碼把我們帶往所謂的constructors。default constructor 意指可以「不需任何引數(shù)就被喚起」者。這樣的一個constructor 如果不是沒有任何參數(shù),就是每個參數(shù)都有預(yù)設(shè)值。通常當(dāng)你需要定義物件陣列時,就會需要一個default constructor

      class A {
      public:
      A(); // default constructor
      };
      A arrayA[10]; // 呼叫constructors 10 次
      class B {
      public:
      B(int x = 0); // default constructor
      };
      B arrayB[10]; // 呼叫constructors 10 次,
      // 每次都給引數(shù)0。
      class C {
      public:
      C(int x); // 這不是一個default constructor
      };
      C arrayC[10]; // 錯誤!
      

      或許有時候你會發(fā)現(xiàn),某個class 的default constructor 有預(yù)設(shè)參數(shù)值,你的編譯器卻拒不接受其物件陣列。例如某些編譯器拒絕接受上述arrayB 的定義,即使它其實符合C++ 標(biāo)準(zhǔn)。這是存在於C++ 標(biāo)準(zhǔn)規(guī)格書和實際編譯器行為之間的一個矛盾例子。截至目前我所知道的每一個編譯器,都有一些這類不相容缺點。在編譯器廠商追上C++ 語言標(biāo)準(zhǔn)之前,請保持你的彈性,並安慰自己,也許不久後的某一天,C++ 編譯器的表現(xiàn)就可以和C++ 標(biāo)準(zhǔn)規(guī)格書所描述的一致了。

      附帶一提,如果你想要產(chǎn)生一個物件陣列,但該物件型別沒有提供default constructor,通常的作法是定義一個指標(biāo)陣列取而代之,然後利用new 一一將每個指標(biāo)初始化:

      C *ptrArray[10]; // 沒有呼叫任何constructors
      ptrArray[0] = new C(22); // 配置並建構(gòu)一個C 物件
      ptrArray[1] = new C(4); // 同上
      ...
      

      這個作法在任何場合幾乎都夠用了。如果不夠,你或許得使用條款14 所說的更高層次(也因此更不為人知)的"placement new" 方法?;氐叫g(shù)語來。所謂copy constructor 係以某物件做為另一同型物件的初值:

      class String {
      public:
      String(); // default constructor
      String(const String& rhs); // copy constructor
      ...
      private:
      char *data;
      };
      String s1; // 呼叫default constructor
      String s2(s1); // 呼叫copy constructor
      String s3 = s2; // 呼叫copy constructor
      

      或許copy constructor 最重要的用途就是用來定義何謂「以by value 方式傳遞和傳回物件」。例如,考慮以下效率不佳的作法,以一個函式串接兩個String 物件:

      const String operator+(String s1, String s2)
      {
      String temp;
      delete [] temp.data;
      temp.data =
      new char[strlen(s1.data) + strlen(s2.data) + 1];
      strcpy(temp.data, s1.data);
      strcat(temp.data, s2.data);
      return temp;
      }
      String a("Hello");
      String b(" world");
      String c = a + b; // c = String("Hello world")
      

      其中operator+ 需要兩個String 物件做為參數(shù),並傳回一個String 物件做為運算結(jié)果。不論參數(shù)或運算結(jié)果都是以by value 方式傳遞,所以在operator+進行過程中,會有一個copy constructor 被喚起,用以將a 當(dāng)做s1 的初值,再有一個copy constructor 被喚起,用以將b 當(dāng)做s2 的初值,再有一個copyconstructor 被喚起,用以將temp 當(dāng)做c 的初值。事實上,只要編譯器決定產(chǎn)生中介的暫時性物件,就會需要一些copy constructor 呼叫動作(見條款M19)。重點是:pass-by-value 便是「呼叫copy constructor」的同義詞。

      順帶一提,你不能夠真的像上述那樣實作Strings 的operator+。傳回一個const String object 是正確的(見條款2123),但是你應(yīng)該以by reference 方式(見條款22)傳遞那兩個參數(shù)

      其實,如果你有外援,並不需要為Strings 撰寫operator+。事實上你的確有外援,因為C++ 標(biāo)準(zhǔn)程式庫(條款49)就內(nèi)含有一個string 型別,帶有一個 operator+,做的事情幾乎就是上述operator+ 的行為。本書中我並用String 和string 兩者(注意前者名稱以大寫開頭,後者否),但方式不同。如果我只是需要一般字串,不在意它是怎麼做出來的,那麼我便使用標(biāo)準(zhǔn)程式庫提供的 string。這也是你應(yīng)該選擇的行為。然而如果我打算剖析C++ 的行為,並因而需要某些實作碼來示範(fàn)或驗證,我便使用非標(biāo)準(zhǔn)的那個String class。身為一個程式員,只要必須用到字串,就應(yīng)該儘可能使用標(biāo)準(zhǔn)的string 型別;那種「開發(fā)自己的字串類別,以象徵具備C++ 某種成熟功力」的日子已經(jīng)過去了(不過你還是有必要瞭解開發(fā)一個像string 那樣的classes 所需知道的課題)。對「示範(fàn)或驗證」目的(而且可說只對此種目的)而言,String 很是方便。無論如何,除非你有很好的理由,否則都不應(yīng)該再使用舊式的char*-based 字串。具有良好定義的string 型別如今已能夠在每一方面比char*s 更具優(yōu)勢,並且更好— 包括其執(zhí)行效率(見條款49和條款M29~M30)。

      接下來兩個需要掌握的術(shù)語是initialization(初始化)和assignment(指派)。物件的初始化行為發(fā)生在它初次獲得一個值的時候。對於「帶有constructors」之 classes 或structs,初始化總是經(jīng)由喚起某個constructor 達成。這和物件的 assignment 動作不同,後者發(fā)生於「已初始化之物件被指派新值」的時候:

      string s1; // initialization(初始化)
      string s2("Hello"); // initialization(初始化)
      string s3 = s2; // initialization(初始化)
      s1 = s3; // assignment(指派)
      

      純粹從操作觀點看,initializationassignment 之間的差異在於前者由constructor 執(zhí)行,後者由operator= 執(zhí)行。換句話說這兩個動作對應(yīng)不同的函式動作。

      C++ 嚴(yán)格區(qū)分此二者,原因是上述兩個函式所考慮的事情不同。Constructors 通常必須檢驗其引數(shù)的有效性(validity),而大部份assignment 運算子不必如此,因為其引數(shù)必然是合法的(因為已被建構(gòu)完成)。另一方面,assignment 動作的目標(biāo)物件並非是尚未建構(gòu)完成的物件,而是可能已經(jīng)擁有配置得來的資源。在新資源可被指派過去之前,舊資源通常必須先行釋放。這裡所謂的資源通常是指記憶體。在assignment 運算子為一個新值配置記憶體之前,必須先釋放舊值的記憶體。
      下面是String 的constructorassignment 運算子的可能作法:

      // 以下是一個可能的String constructor
      String::String(const char *value) {
      {
      if (value) { // 如果指標(biāo)value 不是null
      data = new char[strlen(value) + 1];
      strcpy(data,value);
      }
      else { // 處理null 指標(biāo)
          //此一「接受一個const char* 引數(shù)」的String constructor,
          //有能力處理傳進來的指標(biāo)為null的情況。標(biāo)準(zhǔn)的string 可沒如此寬容。
          //企圖以一個null 指標(biāo)產(chǎn)生一個string,其結(jié)果未有定義。
          //不過以一個空的char*-based 字串(例如"")產(chǎn)生一個string 物件,
          //倒是安全的。
      data = new char[1];
      }
      }
      // 以下是一個可能的String assignment 運算子
      String& String::operator=(const String& rhs)
      {
      if (this == &rhs)
      return *this; // 見條款17
      delete [] data; // 刪除(釋放)舊有的記憶體
      data = // 配置新的記憶體
      new char[strlen(rhs.data) + 1];
      strcpy(data, rhs.data);
      return *this; // 見條款15
      }
      

      注意,constructor 必須檢驗其參數(shù)的有效性,並確保member data 都被適當(dāng)?shù)爻跏蓟?/FONT>,例如一個char* 指標(biāo)必須被適當(dāng)?shù)丶由蟦ull 結(jié)束字元。亦請注意 assignment 運算子認(rèn)定其參數(shù)是合法的,反倒是它會偵測諸如「自己指派給自己」這樣的病態(tài)情況(見條款17),或是集中心力確?!概渲眯掠洃涹w之前先釋放舊有記憶體」。這兩個函式的差異,象徵物件初始化(initialization)和物件指派(assignment)兩者的差異。順帶一提,如果delete [] 這樣的表示法對你而言很陌生,條款5 和條款M8 應(yīng)該能夠消除你的任何相關(guān)疑惑。

      我要討論的最後一個術(shù)語是client(客戶)。Client 代表任何「使用你所寫的碼」的人。當(dāng)我在本書提及clients,我指的便是任何觀察你的碼並企圖理解它們的人。我也是指閱讀你的class 定義並企圖決定是否可以繼承它們的人。我同時也是指那些審查你的設(shè)計並希望洞察其中原理的人。你或許還不習(xí)慣去想到你的clients,但是我會儘量說服你設(shè)法讓他們的生活愉快一些。畢竟,你也是他人所開發(fā)的軟體的client,難道你不希望那些人讓你的生活愉快一些嗎?此外,也許有一天你會發(fā)現(xiàn)你必須使用自己所寫的碼(譯註:指那些classes 或libraries),那時候你的client 就是你自己。

      我在本書用了兩個你可能不甚熟悉的C++ 性質(zhì),它們都是晚近才加入C++ 標(biāo)準(zhǔn)之中。第一個是bool 型別,其值若非true 就是false(兩者都是關(guān)鍵字)。語言內(nèi)建的相對關(guān)係運算子(如<, >, ==)的傳回型別都是bool,if, for, while, do 等述句的條件判斷式的傳回型別也是bool。如果你的編譯器尚未實作出bool 型別,你可以利用typedef 模擬bool,再以兩個const 物件模擬true 和false:

      typedef int bool;
      const bool false = 0;
      const bool true = 1;
      

      這種手法相容於傳統(tǒng)的C/C++ 語意。使用這種模擬作法的程式,在移植到一個支援bool 型別的編譯器平臺後,行為並不會改變。如果你想知道另一種bool 模擬法,包括其優(yōu)缺點討論,請參考More Effective C++ 的導(dǎo)讀部份。

      第二個新特性其實有四樣?xùn)|西,分別是static_cast, const_cast, dynamic_cast, reinterpret_cast 四個轉(zhuǎn)型運算子。傳統(tǒng)的C 轉(zhuǎn)型動作如下:

      (type) expression // 將expression 轉(zhuǎn)為type 型別

      新的轉(zhuǎn)型動作則是這樣:

      static_cast(expression) // 將expression 轉(zhuǎn)為type 型別
      const_cast(expression)
      dynamic_cast(expression)
      reinterpret_cast(expression)
      

      這些不同的轉(zhuǎn)型運算子有不同的作用:

      const_cast 用來將物件或指標(biāo)的常數(shù)性(constness)轉(zhuǎn)型掉,我將在條款21驗證這個主題。
      dynamic_cast 用來執(zhí)行「安全的向下轉(zhuǎn)型動作(safe downcasting)」,這是條款39 的主題。
      reinterpret_cast 的轉(zhuǎn)型結(jié)果取決於編譯器— 例如在函式指標(biāo)型別之間做轉(zhuǎn)型動作。你大概不常需要用到reinterpret_cast。本書完全沒有用到它。
      static_cast 是個「雜物袋」:沒有其他適當(dāng)?shù)霓D(zhuǎn)型運算子可用時,就用這個。它最接近傳統(tǒng)的C 轉(zhuǎn)型動作。

      傳統(tǒng)的C 轉(zhuǎn)型動作仍然合法,但是新的轉(zhuǎn)型運算子比較受歡迎。它們更容易在程式碼中被識別出來(不論是對人類或是對諸如grep 等工具而言),而且愈是縮小範(fàn)圍地指定各種轉(zhuǎn)型運算子的目標(biāo),編譯器愈有可能診斷出錯誤的運用。例如,只有const_cast 才可以用來將某物的常數(shù)性(constness)轉(zhuǎn)換掉。如果你嘗試使用其他轉(zhuǎn)型運算子來轉(zhuǎn)換物件或指標(biāo)的常數(shù)性,一定會踢到鐵板。

      欲知這些新式轉(zhuǎn)型動作的更多資訊,請看條款M2,或查閱較新的C++ 語言書籍。 M 代表More Effective C++,是我的另一本書。本書最後附有一份該書摘要。

      本書的程式範(fàn)例中,我設(shè)法為objects, classes, functions 取一些有意義的名稱。許多書籍在選用識別名稱時,都喜歡恪守一句箴言:簡短是智慧的靈魂,但是我不,我喜歡一切都交待得清清楚楚。我努力打破傳統(tǒng),堅不使用那種隱秘而不易為人識破天機的名稱。但偶爾我會被誘惑所屈服,使用兩個我最歡迎的參數(shù)名稱。其意義可能並不淺顯易懂,特別是如果你從未在任何編譯器開發(fā)團隊待過的話。

      這兩個參數(shù)名稱是lhs 和rhs,分別意味"left-hand side"(左端)和"right-hand side"(右端)。我以它們做為二元運算子各函式的參數(shù)名稱,尤其是operator== 和算術(shù)運算子如operator*。舉個例子,如果a 和b 代表兩個分?jǐn)?shù)(rational numbers)物件,而如果分?jǐn)?shù)可經(jīng)由一個non-member function operator* 相乘,那麼算式:

      a * b

      等於這款形式的函式呼叫:

      operator*(a, b)

      我將宣告operator* 如下(一如你在條款23所見):

      const Rational operator*(const Rational& lhs,const Rational& rhs);

      如你所見,左運算元a 成為函式中的lhs,右運算元b 成為函式中的rhs。

      我也利用縮寫字來為指標(biāo)命名,規(guī)則如下:「指向型別T 之物件」的指標(biāo),我稱為pt,意思是"pointer to T"。下面是幾則例子:

      string *ps; // ps = ptr to string
      class Airplane;
      Airplane *pa; // pa = ptr to Airplane
      class BankAccount;
      BankAccount *pba; // pba = ptr to BankAccount
      

      對於references,我亦採用類似習(xí)慣。也就是說,rs 大約就是一個reference-tostring, ra 則可能是一個reference-to-Airplane。

      當(dāng)我談到member functions,偶而我會使用mf 這個名稱。

      為避免任何混淆,任何時候我在書中提到「C 程式設(shè)計」時,我說的是ISO/ANSI 版的C 語言,而不是舊式的、沒那麼strongly-typed(強型式)的古典C 語言。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多