Header <boost/io/ios_state.hpp
>頭文件 boost/io/ios_state.hpp 用於保存在 C++ IOStreams 系統中的對象的流狀態。
有時某個值需要限定於一定的代碼範圍內變化。Saver 保存器類保存了某個對象(或對象的外表)的當前狀態,並在析構時恢復該對象的狀態,恢復所有對該對像所做的改變。
保存器類的策略有助於使用 I/O 流對象。操縱子對像會在輸入或輸出時改變流的某些狀態。被操縱子改變了的狀態在I/O事務之後會保持新的值。如果操縱子是用在一個不期望流狀態的修改影響到外部的函數中時,這就會成為一個問題。
#include <ostream>
#include <ios>
void hex_my_byte( std::ostream &os, char byte )
{
os << std::hex << static_cast<unsigned>(byte);
}
在調用了 hex_my_byte 之後,os 流會保持其新的十六進制打印模式。通過通過手工調用流狀態的檢查成員函數和修改成員函數來保存和恢復流的打印模式。如果主程序的功能非常複雜和/或需要異常安全性,那麼這種手工的方法就太笨拙了。保存器類可以實現更好的"資源獲得即初始化"的策略。
更好的代碼請見以下 example例子, 使用了保存器類。
#include <iosfwd> // for std::char_traits (declaration)
namespace boost
{
namespace io
{
class ios_flags_saver;
class ios_precision_saver;
class ios_width_saver;
class ios_base_all_saver;
template < typename Ch, class Tr = ::std::char_traits<Ch> >
class basic_ios_iostate_saver;
template < typename Ch, class Tr = ::std::char_traits<Ch> >
class basic_ios_exception_saver;
template < typename Ch, class Tr = ::std::char_traits<Ch> >
class basic_ios_tie_saver;
template < typename Ch, class Tr = ::std::char_traits<Ch> >
class basic_ios_rdbuf_saver;
template < typename Ch, class Tr = ::std::char_traits<Ch> >
class basic_ios_fill_saver;
template < typename Ch, class Tr = ::std::char_traits<Ch> >
class basic_ios_locale_saver;
template < typename Ch, class Tr = ::std::char_traits<Ch> >
class basic_ios_all_saver;
typedef basic_ios_iostate_saver<char> ios_iostate_saver;
typedef basic_ios_iostate_saver<wchar_t> wios_iostate_saver;
typedef basic_ios_exception_saver<char> ios_exception_saver;
typedef basic_ios_exception_saver<wchar_t> wios_exception_saver;
typedef basic_ios_tie_saver<char> ios_tie_saver;
typedef basic_ios_tie_saver<wchar_t> wios_tie_saver;
typedef basic_ios_rdbuf_saver<char> ios_rdbuf_saver;
typedef basic_ios_rdbuf_saver<wchar_t> wios_rdbuf_saver;
typedef basic_ios_fill_saver<char> ios_fill_saver;
typedef basic_ios_fill_saver<wchar_t> wios_fill_saver;
typedef basic_ios_locale_saver<char> ios_locale_saver;
typedef basic_ios_locale_saver<wchar_t> wios_locale_saver;
typedef basic_ios_all_saver<char> ios_all_saver;
typedef basic_ios_all_saver<wchar_t> wios_all_saver;
class ios_iword_saver;
class ios_pword_saver;
class ios_all_word_saver;
}
}
基本的保存器有以下格式:
class saver_class
{
typedef std::ios_base state_type;
typedef implementation_defined aspect_type;
explicit saver_class( state_type &s );
saver_class( state_type &s, aspect_type const &new_value );
~saver_class();
void restore();
};
state_type 是 IOStreams 的基類
std::ios_base. 用戶通常會將一個真正的輸入、輸出或組合的流對像作為 state-type 參數,而不是用基類對象。第一個構造函數接受一個流對象,保存流的一個引用,以及特定的流屬性的當前值。第二個構造函數與第一個類似,但使用第二個參數來將流的屬性改變為給定的 aspect_type 值。析構函數將流的屬性恢復為保存的值。屬性恢復可以(且常常)使用 restore 成員函數提前執行。
| 類 | 保存的屬性 | 屬性類型 | 讀方法 | 寫方法 |
|---|---|---|---|---|
boost::io::ios_flags_saver |
格式控制標誌 | std::ios_base::fmtflags |
flags |
flags |
boost::io::ios_precision_saver |
小數點後的打印位數 | std::streamsize |
precision |
precision |
boost::io::ios_width_saver |
打印對象的最小字段寬度 | std::streamsize |
width |
width |
保存器類模板有以下格式:
template < typename Ch, class Tr >
class saver_class { typedef std::basic_ios<Ch, Tr> state_type; typedef implementation_defined aspect_type;
explicit saver_class( state_type &s );
saver_class( state_type &s, aspect_type const &new_value );
~saver_class();
void restore();
};
state_type 是 IOStreams 的基類模板 std::basic_ios<Ch, Tr> 的一個版本,其中
Ch 是字符類型,Tr 是字符特性類。用戶通常會將一個真正的輸入、輸出或組合的流對像作為 state-type 參數,而不是用基類對象。第一個構造函數接受一個流對象,保存流的一個引用,以及特定的流屬性的當前值。第二個構造函數與第一個類似,但使用第二個參數來將流的屬性改變為給定的 aspect_type 值。析構函數將流的屬性恢復為保存的值。屬性恢復可以(且常常)使用 restore 成員函數提前執行。
| 類模板 | 保存的屬性 | 屬性類型 | 讀方法 | 寫方法 |
|---|---|---|---|---|
boost::io::basic_ios_iostate_saver<Ch, Tr> |
流的失敗狀態[1], [2] | std::ios_base::iostate |
rdstate |
clear |
boost::io::basic_ios_exception_saver<Ch, Tr> |
哪一個失敗狀態引發了異常 [1] | std::ios_base::iostate |
exceptions |
exceptions |
boost::io::basic_ios_tie_saver<Ch, Tr> |
流所同步的輸出流同步 | std::basic_ostream<Ch, Tr> * |
tie |
tie |
boost::io::basic_ios_rdbuf_saver<Ch, Tr> |
流所關聯的流緩衝 [2] | std::basic_streambuf<Ch, Tr> * |
rdbuf |
rdbuf |
boost::io::basic_ios_fill_saver<Ch, Tr> |
用於填充過寬字段的字符 | Ch |
fill |
fill |
boost::io::basic_ios_locale_saver<Ch, Tr> |
流所關聯的Locale 信息 [3] | std::locale |
getloc (from std::ios_base) |
imbue (from std::basic_ios<Ch, Tr>) |
std::basic_ios<Ch, Tr> 類來取出它們的信息,雖然它可能使用了 std::ios_base 中的功能。問題是,在 ios_base 中所需的成員函數的版本並不是多態地關聯到 basic_ios 中。保存器類中要使用的流將使用繼承層次中最接近的成員函數,即
basic_ios 中的函數。用戶自定義格式化信息的保存器類有以下格式:
#include <iosfwd> // for std::ios_base (declaration)
class saver_class
{
typedef std::ios_base state_type;
typedef int index_type;
typedef implementation_defined aspect_type;
explicit saver_class( state_type &s, index_type i );
saver_class( state_type &s, index_type i, aspect_type const &new_value );
~saver_class();
void restore();
};
索引 i 用於區分特定的用戶自定義格式化屬性。該索引只能在運行期確定(就像靜態成員函數 std::ios_base::xalloc)。
state_type 是 IOStreams 的基類
std::ios_base. 用戶通常會將一個真正的輸入、輸出或組合的流對像作為 state-type 參數,而不是用基類對象。第一個構造函數接受一個流對象,保存流的一個引用,以及特定的流屬性的當前值。第二個構造函數與第一個類似,但使用第二個參數來將流的屬性改變為給定的 aspect_type 值。析構函數將流的屬性恢復為保存的值。屬性恢復可以(且常常)使用 restore 成員函數提前執行。
| 類 | 保存的屬性 | 屬性類型 | 引用方法 |
|---|---|---|---|
boost::io::ios_iword_saver |
數字的用戶自定義格式標誌 | long |
iword |
boost::io::ios_pword_saver |
指針的用戶自定義格式標誌 | void * |
pword |
有三個類(模板)用作組合屬性的保存器。boost:io::ios_base_all_saver 保存器類組合了所有基本屬性保存器類的功能。它有一個構造函數,接受要保存狀態的流。boost::io::basic_ios_all_saver 組合了所有增強屬性保存器類模板以及組合基本屬性保存器類的功能。它有一個構造函數,接受要保存狀態的流。boost::io::ios_all_word_saver 保存器類組合了保存自定義格式化信息的保存器類。它的構造函數接受要保存屬性的流以及用戶自定義屬性的索引。每一個類的析構函數都恢復保存的狀態。屬性恢復可以(且常常)使用 restore 成員函數提前執行。
在 rationale原理
一節中使用的代碼可以從兩個地方進行改進。打印函數可以在改變格式狀態的代碼的周圍使用一個保存器。或者在調用的函數中用一個保存器包圍這個調用。或者兩
者都做,尤其是在用戶不知道打印函數是否使用了狀態保存器時。如果用戶想要前後的一系列改變,而不想將每次改變都包在一個單獨的代碼塊中,則可以在每次嘗
試間調用 restore 成員函數。
#include <boost/io/ios_state.hpp>
#include <ios>
#include <iostream>
#include <ostream>
void new_hex_my_byte( std::ostream &os, char byte )
{
boost::io::ios_flags_saver ifs( os );
os << std::hex << static_cast<unsigned>(byte);
}
int main()
{
using std::cout;
using std::cerr;
//...
{
boost::io::ios_all_saver ias( cout );
new_hex_my_byte( cout, 'A' );
}
//...
{
boost::io::ios_all_saver ias( cerr );
new_hex_my_byte( cerr, 'b' );
ias.restore();
new_hex_my_byte( cerr, 'C' );
}
//...
}
restore member functions, based on suggestions
by Gennadiy Rozental and Rob Stewart
Revised: 28 February 2005
Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)