#include const int null_pointer_reference = -1; template class smart_ptr { public: T* operator->() const {if(ptr) return ptr; throw null_pointer_reference;} T& operator*() const {if(ptr) return *ptr; throw null_pointer_reference;} smart_ptr():ptr(NULL) {} smart_ptr(T* p):ptr(p) {} ~smart_ptr() {delete(ptr); ptr = NULL;} smart_ptr& operator=(T* p) {delete(ptr); ptr = p; return *this;} private: smart_ptr& operator=(const smart_ptr& s) {} //smart_ptr(smart_ptr& s):ptr(NULL) {} protected: T* ptr; }; class myclass { public: int a; int b; myclass() {printf("\n new myclass object created.");} ~myclass() {printf("\n myclass object deleted.");} }; //test1: one smart_ptr assgined twice void test1() { smart_ptr pObj1 = new myclass; pObj1->a = 100; pObj1 = new myclass; } //test2: assigning one smart_ptr to another void test2() { smart_ptr pObj1; pObj1 = new myclass; //enable the following to see the program crash //smart_ptr pObj2 = pObj1; //pObj2 = pObj1; } //test3: using uninitialized pointer void test3() { try { smart_ptr pObj1; pObj1->a = 100; } catch(int e) { if (e == null_pointer_reference) printf("\n null pointer referenced"); } } //test4: constness void test4() { const smart_ptr pObj1 = new myclass; pObj1->a = 100; } int main() { printf("\ntest1"); test1(); printf("\ntest2"); test2(); printf("\ntest3"); test3(); printf("\ntest4"); test4(); printf("\nend of program\n"); return 0; }