, (--, setjmp/longjmp), . , , , :
int function1(Error& e, char * arg)
{
if(e.failure())
return -1;
}
int function2(Error& e, int arg)
{
if(e.failure())
return -1;
}
int function3(Error& e, char * arg)
{
if(e.failure())
return -1;
return function2(e, function1(e, arg));
}
:
class Base1
{
protected:
Base1(Error& e)
{
if(e.failure())
return;
}
};
class Base2
{
protected:
Base2(Error& e)
{
if(e.failure())
return;
}
};
class Derived: public Base1, public Base2
{
public:
Derived(Error& e): Base1(e), Base2(e)
{
if(e.failure())
return;
...
}
};
, . new :
void * operator new(Error& e, size_t n)
{
if(e.failure())
return NULL;
void * p = ::operator new(n, std::nothrow_t());
if(p == NULL)
;
return p;
}
template<class T> T * guard_new(Error& e, T * p)
{
if(e.failure())
{
delete p;
return NULL;
}
return p;
}
:
Derived o = guard_new(e, new(e) Derived(e));
:
- C ( Error )
- The Error class can be 100% opaque; using macros to access, declare and transmit it, it can include all kinds of information, including, but not limited to, the source file and line, function name, backtrack of the stack, etc.
- this refers to rather complex expressions, which makes it almost like an exception in many cases
source
share