1、面向對象的標準庫
實際的程序不僅限於對控制窗口的IO,通常還需要讀或寫已命名的文件。此外,程序還應該能夠方便地使用IO操作格式化內存中的數據,從而避免讀寫磁盤或其他設備的複雜性和運行代價。應用程序還需要支持寬字符語言的讀寫。
從概念上看,無論是設備的類型還是字符的大小,都不影響需要執行的IO操作。要同時支持不同的設備和不同大小的字符流,標準庫使用了繼承來定義一組面向對象的類。一般而言,通過繼承關聯起來的類型都共享公共的接口。如果兩個類型存在繼承關係,則可以說一個類(派生類)“繼承”了其父類(基類)的行爲——接口。
IO類型在三個獨立的頭文件中定義:iostream定義讀寫控制窗口的類型,fstream定義讀寫已命名文件的類型,而sstream定義的類型則用於讀寫存儲在內存中的string對象。在fstream和sstream裏定義的每種類型都是從iostream頭文件裏定義的相關類型派生而來。
頭文件iostream中包含的類型:istream 從流中讀取,ostream寫入到流中去,iostream對流進行讀寫,從istream和ostream派生而來。
頭文件fstream中包含的類型:ifstream從文件中讀取,由istream派生而來;ofstream寫到文件中去,由ostream派生而來;fstream讀寫文件,由iostream派生而來。
頭文件sstream中包含的類型:istringstream從string對象中讀取,由istream派生而來;
ostringstream寫到string對象中去,由ostream派生而來;
stringstream對string對象進行讀寫,由iostream派生而來。
由於ifstream和istringstream類型繼承自istream類,故讀istream對象的程序也可用於讀文件(ifstream)或者string對象(istringstream)。類似地,提供輸出功能的程序同樣可用於ofstream或ostringstream取代ostream類型實現。除istream和ostream類型之外,iostream頭文件還定義了iostream類型。iostream類型繼承自istream和ostream。這意味着iostream對象共享了他的兩個父類的接口。iostream類型在同一個輸入流上實現輸入和輸出操作。
對IO類使用繼承的另外一個含義:如果函數有基類類型的引用形參時,可以給函數傳遞其派生類型的對象。這樣就可以編寫一個函數,而將它應用到三種類型的流上:控制檯、磁盤文件或者字符串流。
IO對象不可以複製或賦值,這個要求有兩層含義:1、只有支持複製的元素類型可以存儲在vector或者其他容器類型裏,因此流對象是不能存儲在vector(或其他)容器中的(即不存在存儲流對象的vector或者其他容器)。2、形參或返回類型也不能爲流類型。如果需要傳遞或返回IO對象,則必須傳遞或返回該對象的指針或引用。
一般情況下,如果要傳遞IO對象以便對它進行讀寫,可用非const引用的方式傳遞這個流對象。對IO對象的讀寫繪改變它的狀態,因此引用必須是非const的。
2、條件狀態
IO標準庫管理一系列的條件狀態成員,用來標記給定的IO對象是否處於可用狀態,或者碰到了哪種特定的錯誤。
strm::iostate 機器相關的整型名,由各個iostream類定義,用於定義條件狀態。
strm::badbit strm::iostate 類型的值,用於指出被破壞的流。
strm::failbit strm::iostate 類型的值,用於指出失敗的IO操作。
strm::eofbit strm::iostate 類型的值,用於指出流已經到達文件結束符。
s.eof() 如果設置了流s的eofbit的值,則該函數返回true。
s.fail() 如果設置了流s的failbit的值,則該函數返回true。
s.bad() 如果設置了流s的badbit的值,則該函數返回true。
s.good() 如果流s處於有效狀態,則該函數返回true。
s.clear() 將流s中的所有狀態都重設爲有效狀態。
s.clear(flag) 將流s中的某個特定條件狀態設置爲有效。flag的類型是strm::iostate。
s.setstate(flag) 給流s添加指定條件。flag的類型是strm::iostate。
s.rdstate(flag) 返回流s的當前條件,返回值類型爲strm::iostate。
流必須處於無錯誤狀態,才能用於輸入或輸出。