條款 2:盡量用<iostream>而不用<stdio.h>
- scanf 和 printf 很輕巧,很高效,事實上 scanf 和 printf 及其系列還可以做些改進,他們不是型別安全的,而且沒有擴展性,因為型別安全和擴展性是 C++的基石,所以也要服從這一點,
- scanf/printf 系列函式把要讀寫的變數和控制讀寫格式的資訊分開來,就象古老的 FORTRAN 那樣,scanf/printf 的這些弱點正是運算子>>和<<的強項:
int i; Rational r; // r 是個有理數 ... cin >> i >> r; cout << i << r;
- 上面的代碼要通過編譯,>>和<<必須是可以處理 Rational 型別物件的多載函式(可能要通過隱式型別轉換),
- 如果沒有實作這樣的函式,就會出錯(處理 int不用這樣做,因為它是標準用法),
- 編譯器自己可以根據不同的變數型別選擇運算子的不同形式,所以不必勞你去指定第一個要讀寫的物件是 int 而第二個是 Rational,
- 在傳遞讀和寫的物件時采用的語法形式相同,所以不必象 scanf 那樣死記一些規定,比如如果沒有得到指標,必須加上地址符,而如果已經得到了指標,又要確定不要加上地址符,這些完全可以交給 C++編譯器去做,編譯器沒別的什么事好做的,而你卻不一樣,最后要注意的是,象 int 這樣的固定類型和象 Rational這樣的自定義型別在讀寫時方式是一樣的,
- 所寫的表示有理數的類的代碼可能象下面這樣:
class Rational { public: Rational(int numerator = 0, int denominator = 1); ... private: int n, d; // 分子,分母 friend ostream& operator<<(ostream& s, const Rational& r); }; ostream& operator<<(ostream& s, const Rational& r) { s << r.n << '/' << r.d; return s; }
- 上面的代碼涉及到 operator<<的一些微妙(但很重要)的用法,
- 例如:上面的 operator<<不是成員函式(條款 19 解釋了為什么),而且,傳遞給 operator<<的不是 Rational 物件,而是定義為 const 的物件的參考(參見條款 22),operator>>的宣告和實作也類似,
- 有些情況下回到那些經過證明而且正確的老路上去還是很有意義的
- 第一,有些 iostream 的操作實作起來比相應的 C stream效率要低,所以不同的選擇會給你的程式有可能(雖然不一定,參見條款 M16)帶來很大的不同,但請牢記,這不是對所有的 iostream 而言,只是一些特殊的實作;參見條款 M23,
- 第二,在標準化的程序中,iostream 庫在底層做了很多修改(參見條款 49),所以對那些要求最大可移植性的應用程式來說,會發現不同的廠商遵循標準的程度也不同,
- 第三,iostream 庫的類有建構式而里的函式沒有,在某些涉及到靜態物件初始化順序的時候,如果可以確認不會帶來隱患,用標準 C 庫會更簡單實用,
- iostream 庫的類和函式所提供的型別安全和可擴展性的價值遠遠超過你當初的想象,所以不要僅僅因為用慣了而舍棄它,畢竟,轉換到 iostream后,也不會忘掉,
- 其實沒有<iostream.h>這樣的東西——標準化委員會在簡化非 C 標準頭檔案時用<iostream>取代了它,
- 他們這樣做的原因在條款 49 進行了解釋,還必須知道的是,如果編譯器同時支持 <iostream>和<iostream.h> ,那頭檔案名的使用會很微妙,
- 例如,如果使用了 #include<iostream>, 得到的是置于名字空間 std(見條款 28)下的 iostream 庫的元素;如果使用#include <iostream.h>,得到的是置于全域空間的同樣的元素,在全域空間獲取元素會導致名字沖突,而設計名字空間的初衷正是用來避免這種名字沖突的發生,還有,打字時<iostream>比<iostream.h>少兩個字,這也是很多人用它的原因,
- 【注】參考《Effective C++》
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/190936.html
標籤:java
