作者:qwer | 来源:互联网 | 2023-09-02 12:08
~
Here is a simple note for c++ exception usage.
#include
#include
#include
class CBad : public std::exception
{
public:
const char* what() const throw () { //`const throw()` means it won't throw any exception.
return "CBad";
}
};
class BBad : public std::exception
{
public:
const char* what() const throw () {
return "BBad";
}
};
class C{
public:
C(int x) throw(CBad){
printf("C(%d)...\n", x);
if (x <0) {
//error
throw CBad();
}
}
~C(){
printf("~C()...\n");
}
};
class B{
public:
B(int x) throw(BBad){
printf("B(%d)...\n", x);
if (x <0) {
throw BBad();
}
}
~B(){
printf("~B()...\n");
}
};
class A{
public:
A(int b, int c)
try: b_(new B(b)),
c_(new C(c))
{
printf("A()...\n");
}
catch (BBad & e) {
std::cout <<"b fucked" < //Q: will "new C(c)" run ? A: won't. so here we don't need to do other things.
throw;
}
catch (CBad & e) { //if no exception introduced, the resources held by B is not going to be released.
std::cout <<"c fucked, but b is ok. so we have to release b's resources." < delete b_;
throw;
}
catch (...) {
throw;
}
~A() {
printf("~A()...\n");
delete b_;
delete c_;
}
private:
B *b_;
C *c_;
};
void custom_termination()
{
abort();
}
int main()
{
try {
A(1, -2);
} catch (...) {
printf("other exception\n");
//if A's construtor generate any exception, we can:
// 1. throw it to higher level ( here the exception will go calling `std::terminate()`. )
// throw;
// 2. continue do other things if this error can be tolarated.
// do nothing;
// 3. custom termination functions.
// ourterminate();
custom_termination();
}
return 0;
}
a further example:
#include
#include
#include
#include
class XBad : public std::exception
{
public:
explicit XBad(const char *msg) throw()
: msg_(msg) {
}
virtual const char* what() const throw () {
return msg_;
}
protected:
const char* msg_;
};
class CBad : public XBad
{
public:
explicit CBad(const char *msg) throw()
: XBad(msg) {
}
explicit CBad(int ec) throw()
: XBad(strerror(ec))
{
}
};
class BBad : public XBad
{
public:
explicit BBad(const char *msg) throw()
: XBad(msg) {
}
};
class C{
public:
C(int x) throw(CBad){
printf("C(%d)...\n", x);
if (x <0) {
//error
throw CBad(x);
}
}
~C(){
printf("~C()...\n");
}
};
class B{
public:
B(int x) throw(BBad){
printf("B(%d)...\n", x);
if (x <0) {
throw BBad(".... is not permit.");
}
}
~B(){
printf("~B()...\n");
}
};
class A{
public:
A(int b, int c)
try: b_(new B(b)),
c_(new C(c))
{
printf("A()...\n");
}
catch (const BBad & e) {
std::cout <<"b fucked" < //Q: will "new C(c)" run ? A: won't. so here we don't need to do other things.
throw e;
}
catch (const CBad & e) { //if no exception introduced, the resources held by B is not going to be released.
std::cout <<"c fucked, but b is ok. so we have to release b's resources." < delete b_;
throw e;
}
catch (...) {
throw XBad("other exception");
}
~A() {
printf("~A()...\n");
delete b_;
delete c_;
}
private:
B *b_;
C *c_;
};
void custom_termination()
{
abort();
}
int main()
{
try {
A(1, -2);
} catch ( const XBad & x ){
printf("Error: %s\n", x.what());
abort();
//if A's construtor generate any exception, we can:
// 1. throw it to higher level ( here the exception will go calling `std::terminate()`. )
// throw;
// 2. continue do other things if this error can be tolarated.
// do nothing;
// 3. custom termination functions.
// ourterminate();
} catch (...) {
printf("other exception\n");
custom_termination();
}
return 0;
}