我有一個特別ornery一段網絡代碼。我正在使用asio,但這對這個問題並不重要。我認爲除了關閉它之外,沒有辦法解除綁定套接字。問題是open()
,bind()
和listen()
都可以拋出system_error
。所以我用一個簡單的try/catch
來處理代碼。代碼寫在破碎的。複雜的錯誤處理
using namespace boost::asio;
class Thing
{
public:
ip::tcp::endpoint m_address;
ip::tcp::acceptor m_acceptor;
/// connect should handle all of its exceptions internally.
bool connect()
{
try
{
m_acceptor.open(m_address.protocol());
m_acceptor.set_option(tcp::acceptor::reuse_address(true));
m_acceptor.bind(m_address);
m_acceptor.listen();
m_acceptor.async_accept(/*stuff*/);
}
catch(const boost::system::system_error& error)
{
assert(acceptor.is_open());
m_acceptor.close();
return false;
}
return true;
}
/// don't call disconnect unless connect previously succeeded.
void disconnect()
{
// other stuff needed to disconnect is ommited
m_acceptor.close();
}
};
的錯誤是,如果插座連接失敗,它會嘗試關閉它在catch塊和亂扔關閉從未被打開的受體另一SYSTEM_ERROR。
一個解決方案是在catch塊中添加一個if(acceptor.is_open())
,但味道不對。有點像混合C
-style錯誤檢查與c++
例外。如果我去哪條路線,我不妨使用open()
的非投擲版本。
boost::system::error_code error;
acceptor.open(address.protocol, error);
if(! error)
{
try
{
acceptor.set_option(tcp::acceptor::reuse_address(true));
acceptor.bind(address);
acceptor.listen();
acceptor.async_accept(/*stuff*/);
}
catch(const boost::system::system_error& error)
{
assert(acceptor.is_open());
acceptor.close();
return false;
}
}
return !error;
是否有使用RAII和try/catch
塊來處理這些可能出現的異常優雅的方式?
我只是錯了頭試圖避免if(error condition)
風格錯誤處理時使用異常?
這包括兩個try-catch塊,其價格昂貴並且不符合RAI C++習慣用法。 – 2010-05-02 18:06:54