Hi, everyone, I'm learning <<thinking c++>volume Two, and testing the
code below.
/////////////////////////////////////////////////////////////////////////////
//: C01:Wrapped.cpp
#include <iostream>
#include <cstddef>
using namespace std;
template<class T, int sz = 1class PWrap {
T* ptr;
public:
class RangeError {}; // Exception class
PWrap() {
ptr = new T[sz];
cout << "PWrap constructor" << endl;
}
~PWrap() {
delete[] ptr;
cout << "PWrap destructor" << endl;
}
T& operator[](int i) throw(RangeErro r) {
if(i >= 0 && i < sz) return ptr[i];
throw RangeError();
}
};
class Cat {
public:
Cat() { cout << "Cat()" << endl; }
~Cat() { cout << "~Cat()" << endl; }
void g() {}
};
class Dog {
public:
void* operator new[](size_t) {
cout << "Allocating a Dog" << endl;
//throw 47; //*************** *************** *NOTE
return 0;
}
void operator delete[](void* p) {
cout << "Deallocati ng a Dog" << endl;
::delete[](p);
}
};
class UseResources {
PWrap<Cat, 3cats;
PWrap<Dogdog;
public:
UseResources() {
cout << "UseResources() " << endl;
}
~UseResources() {
cout << "~UseResources( )" << endl;
}
void f() { cats[1].g(); }
};
int main() {
try {
UseResources ur;
} catch(int) {
cout << "inside handler" << endl;
} catch(...) {
cout << "inside catch(...)" << endl;
}
}
/////////////////////////////////////////////////////////////////////////////////
In the UseResources class, It will create *Three cats* and *One dog*,
When I comment the "throw 47" line in the class Dog implementation.
it has the result output:
=============== =============== ===
Cat()
Cat()
Cat()
PWrap constructor
Allocating a Dog
PWrap constructor
UseResources()
~UseResources()
Deallocating a Dog
PWrap destructor
~Cat()
~Cat()
~Cat()
PWrap destructor
=============== =============== ====
But When I uncomment the "throw 47" line, the result will be:
=============== =============== ===
Cat()
Cat()
Cat()
PWrap constructor
Allocating a Dog
~Cat()
~Cat()
~Cat()
PWrap destructor
inside handler
=============== =============== ====
It seems that an exception happened when we are create the Dog object.
My Question:
When an exception occurred in the allocate a Dog object,
Why was *~UseResources( )* not called?
Why was *~Cat()* called?
How does the "exception mechanism" guarantee that the allocated object
will be cleared.
Someone can give this a brief trick? Is it about call stack unwinding?
Thank you very much.
code below.
/////////////////////////////////////////////////////////////////////////////
//: C01:Wrapped.cpp
#include <iostream>
#include <cstddef>
using namespace std;
template<class T, int sz = 1class PWrap {
T* ptr;
public:
class RangeError {}; // Exception class
PWrap() {
ptr = new T[sz];
cout << "PWrap constructor" << endl;
}
~PWrap() {
delete[] ptr;
cout << "PWrap destructor" << endl;
}
T& operator[](int i) throw(RangeErro r) {
if(i >= 0 && i < sz) return ptr[i];
throw RangeError();
}
};
class Cat {
public:
Cat() { cout << "Cat()" << endl; }
~Cat() { cout << "~Cat()" << endl; }
void g() {}
};
class Dog {
public:
void* operator new[](size_t) {
cout << "Allocating a Dog" << endl;
//throw 47; //*************** *************** *NOTE
return 0;
}
void operator delete[](void* p) {
cout << "Deallocati ng a Dog" << endl;
::delete[](p);
}
};
class UseResources {
PWrap<Cat, 3cats;
PWrap<Dogdog;
public:
UseResources() {
cout << "UseResources() " << endl;
}
~UseResources() {
cout << "~UseResources( )" << endl;
}
void f() { cats[1].g(); }
};
int main() {
try {
UseResources ur;
} catch(int) {
cout << "inside handler" << endl;
} catch(...) {
cout << "inside catch(...)" << endl;
}
}
/////////////////////////////////////////////////////////////////////////////////
In the UseResources class, It will create *Three cats* and *One dog*,
When I comment the "throw 47" line in the class Dog implementation.
it has the result output:
=============== =============== ===
Cat()
Cat()
Cat()
PWrap constructor
Allocating a Dog
PWrap constructor
UseResources()
~UseResources()
Deallocating a Dog
PWrap destructor
~Cat()
~Cat()
~Cat()
PWrap destructor
=============== =============== ====
But When I uncomment the "throw 47" line, the result will be:
=============== =============== ===
Cat()
Cat()
Cat()
PWrap constructor
Allocating a Dog
~Cat()
~Cat()
~Cat()
PWrap destructor
inside handler
=============== =============== ====
It seems that an exception happened when we are create the Dog object.
My Question:
When an exception occurred in the allocate a Dog object,
Why was *~UseResources( )* not called?
Why was *~Cat()* called?
How does the "exception mechanism" guarantee that the allocated object
will be cleared.
Someone can give this a brief trick? Is it about call stack unwinding?
Thank you very much.
Comment