【发布时间】:2010-04-28 15:37:19
【问题描述】:
我有一段特别难看的网络代码。我正在使用 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 风格的错误检查与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 ) 样式错误处理是不是我的想法是错误的?
【问题讨论】:
标签: c++ exception exception-handling