Ответ 1
вы не можете обнаружить это, и вы этого не хотите. это не ваш классовый бизнес. если кто-то вызовет вас из-за отсутствия деструктора, он поймает исключения
Это будет следствием Почему Alexandrescu не использует std:: uncaught_exception() для реализации SCOPE_FAIL в ScopeGuard11?
Я хотел бы определить, создает ли кто-то MyClass
в деструкторе другого класса (или с активным деструктором где-то в стеке вызовов).
class MyClass
{
public:
MyClass(){
assert(???what to put here????);
}
}
void f(){
MyClass m; //whether this asserts should be context dependant
}
class OtherClass{
~OtherClass(){
MyClass m; //this should assert
f(); //this should too;
}
}
int main()
{
MyClass m; //this should not assert
f(); //this should also not assert
}
Одна попытка может быть:
assert(!std::uncaught_exception());
но это будет работать только в том случае, если деструктор вызывается из-за исключения, а не если он вызывается, потому что объект вышел из области видимости.
вы не можете обнаружить это, и вы этого не хотите. это не ваш классовый бизнес. если кто-то вызовет вас из-за отсутствия деструктора, он поймает исключения
Вы не можете определить, как вызывается ваша функция, если вы не предоставите эту информацию своим абонентам.
Также, как я помню, Visual С++ никогда не реализовывал std::uncaught_exception
, поэтому это было бы непригодным (для переносимого кода) даже там, где было известно, что ни один деструктор не вызвал какой-либо блок try
.
Однако, тривиально, чтобы определить, выходит ли область из-за исключения или нет.
Просто поставьте эту область в try
-block; что за это.
Например,
class Transaction
{
private:
bool failed_;
Transaction( Transaction const& ); // deleted
Transaction& operator=( Transaction const& ); // deleted
public:
void fail() { failed_ = true; }
void commit() { ... }
// More functionality, then
~Transaction()
{
if( failed_ ) { rollback(); }
}
Transaction(): failed_( false ) {}
};
void foo()
{
Transaction transaction;
try
{
// blah blah
}
catch( ... )
{
transaction.fail();
throw;
}
}
Отказ от ответственности: я не использовал этот шаблон, поэтому не могу подтвердить, насколько он практичен.