我想我应该做一些关于例外情况的调查。
根据这个问题(C++ catching all exceptions),答案之一是:
catch(...)将捕获所有C++异常,但它应该被认为是错误的设计。
目前,我已经采用了这样的方法:
CPTSDatabase::~CPTSDatabase()
{
try
{
CloseDatabase();
}
catch(...)
{
}
}
void CPTSDatabase::CloseDatabase()
{
if (m_dbDatabase.IsOpen())
m_dbDatabase.Close();
}我认为这是正确的方法,因为当我跟踪到CDatabase::Close()时,它会做一些类似的事情:
// Disconnect connection
void CDatabase::Close()
{
ASSERT_VALID(this);
// Close any open recordsets
AfxLockGlobals(CRIT_ODBC);
TRY
{
while (!m_listRecordsets.IsEmpty())
{
CRecordset* pSet = (CRecordset*)m_listRecordsets.GetHead();
pSet->Close(); // will implicitly remove from list
pSet->m_pDatabase = NULL;
}
}
CATCH_ALL(e)
{
AfxUnlockGlobals(CRIT_ODBC);
THROW_LAST();
}
END_CATCH_ALL
AfxUnlockGlobals(CRIT_ODBC);
if (m_hdbc != SQL_NULL_HDBC)
{
RETCODE nRetCode;
AFX_SQL_SYNC(::SQLDisconnect(m_hdbc));
AFX_SQL_SYNC(::SQLFreeConnect(m_hdbc));
m_hdbc = SQL_NULL_HDBC;
_AFX_DB_STATE* pDbState = _afxDbState;
AfxLockGlobals(CRIT_ODBC);
ASSERT(pDbState->m_nAllocatedConnections != 0);
pDbState->m_nAllocatedConnections--;
AfxUnlockGlobals(CRIT_ODBC);
}
}CDatabase::Close文档甚至没有说明抛出的异常。
联系起来的答案是:
您可以使用c++11的新
current_exception机制。
考虑到我们正在使用的CDatabase类,还不清楚我们是否可以使用这种方法。
发布于 2021-10-22 21:50:02
由于CDatabase::Close()使用THROW_LAST来抛出CDBException,所以您必须使用catch (CDBException* e)。即使您没有处理它,您仍然必须Delete错误。当直接调用CDatabase方法时,您也可以这样做:
void CPTSDatabase::CloseDatabase()
{
try
{
if (m_dbDatabase.IsOpen())
m_dbDatabase.Close();
}
catch (CDBException* e)
{
//TRACE(L"DB error: " + e->m_strError);
e->Delete();
}
}或使用
CPTSDatabase::~CPTSDatabase()
{
try { CloseDatabase(); }
catch (CDBException* e) { e->Delete(); }
catch(...) {}
}因为在这段代码中,不清楚异常来自何处。catch(...) {}将处理其他例外情况。通常不推荐catch(...) {},因为它没有提供有用的信息,它只是说“出了问题.”
只有在您在自己的代码中添加throw或使用std函数时,才使用标准库异常。示例:
try { std::stoi("wrong argument"); }
catch (const std::exception& e) { TRACE("%s\n", e.what()); }
try { throw 123; }
catch (int i) { TRACE("%d\n", i); }https://stackoverflow.com/questions/69682609
复制相似问题