///////////////////////////////////////////////////////////////////// // smartPtr.cpp - demonstrates use of smart pointers to manage // // heap-based objects // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2002 // ///////////////////////////////////////////////////////////////////// #include #include #include #include "smartPtr.h" #include "trace.h" using namespace std; //-----< test stub >------------------------------------------- #ifdef TEST_SMARTPTR ///////////////////////////////////////////////////////////////////// // a structure type used in a demonstration of smart pointers // struct aStructType { int x; double y; char z; string show(); }; string aStructType::show() { ostringstream oss; oss << "\n {" << x << ", " << y << ", " << z << "}"; return oss.str(); } ostream& operator<<(ostream &out, aStructType &ast) { out << ast.show(); return out; } class tracer { public: ~tracer() { string temp = "there currently exist "; temp += toString(smartPtr::objectsAllocated()); temp += " double objects"; trace(temp.c_str()); temp = "there currently exist "; temp += toString(smartPtr::objectsAllocated()); temp += " aStructType objects"; trace(temp.c_str()); cout << endl; } }; // //----< entry point >------------------------------------------------ void main() { const char *titleStr = "Demonstration of Smart Pointer Type for use with objects on heap"; cout << endl << stitle(titleStr,'=') << endl; ////////////////////////////////////////////////////////////////////// title("construction and dereferencing of a single double object",'-'); ////////////////////////////////////////////////////////////////////// smartPtr sp0; *sp0 = 3.1415927; trace("value of 1st smartly pointed double is: ", *sp0); smartPtr sp1(0.5); trace("value of 2nd smartly pointed double is: ", *sp1); trace(""); //////////////////////////////////////////////////////////// title("construction and access to array of double objects"); //////////////////////////////////////////////////////////// double d[5] = { 0.5, 1.5, -2.5, 3.5, -4.5 }; smartPtr sp2(d,5); int i; for(i=0; i<5; i++) trace("value: ",sp2[i]); trace(""); ///////////////////////////////////////////////////////////////// title("using index operator to modify array of doubles on heap"); ///////////////////////////////////////////////////////////////// sp2[0] = -0.5; sp2[2] = 2.5; for(i=0; i<5; i++) trace("value: ",sp2[i]); trace(""); // ///////////////////////////////////////////// // check number of double objects allocated ///////////////////////////////////////////// trace( "double objects allocated so far = ", smartPtr::objectsAllocated() ); cout << endl; /////////////////////////////////////////////////////////// title("copy construction of smart pointer does deep copy"); /////////////////////////////////////////////////////////// smartPtr sp3 = sp2; for(i=0; i<5; i++) trace("value: ",sp2[i]); trace(""); ////////////////////////////////////////// title("assignment also does a deep copy"); ////////////////////////////////////////// for(i=0; i > vecStructs; vecStructs.reserve(2); vecStructs.push_back(aStruct); vecStructs.push_back(aStruct); vecStructs.push_back(aStruct); cout << vecStructs[0]->show(); cout << vecStructs[1]->show(); cout << vecStructs[2]->show() << endl; ///////////////////////////////////////////////////////////////// trace("assign a new structure value to one of the heap objects"); title(" by dereferencing the vector container's smart pointer "); ///////////////////////////////////////////////////////////////// aStruct.x = 23; aStruct.y = 3.1415927; *vecStructs[1] = aStruct; cout << vecStructs[0]->show(); cout << vecStructs[1]->show(); cout << vecStructs[2]->show() << endl; ////////////////////////////////////////////////////////////////// trace("modify one of the heap-based structures by dereferencing"); title(" its smart pointer "); ///////////////////////////////////////////////////////////////// vecStructs[0]->x = 3333; vecStructs[0]->y = -0.3333; vecStructs[0]->z = 'A'; cout << vecStructs[0]->show(); cout << vecStructs[1]->show(); cout << vecStructs[2]->show() << endl; /////////////////////////////////////////////////////// title("check number of aStructType objects allocated"); /////////////////////////////////////////////////////// trace( "aStructType objects allocated = ", smartPtr::objectsAllocated() ); trace(""); // ////////////////////////////////////////////////////////////////////////// trace("define a vector of smart pointers in a local block and show that"); title(" referenced objects are deleted when vector goes out of scope "); ////////////////////////////////////////////////////////////////////////// { vector< smartPtr > newVecStructs = vecStructs; cout << "\n after constructing new vecStructs in local scope:"; trace( "aStructType objects allocated = ", smartPtr::objectsAllocated() ); } cout << "\n after leaving local scope:"; trace( "aStructType objects allocated = ", smartPtr::objectsAllocated() ); cout << endl; ////////////////////////////////////////////////////////// trace("check deallocation of currently existing objects"); title(" of each smart pointer type "); ////////////////////////////////////////////////////////// smartPtr::verbose(true); smartPtr::verbose(true); tracer dtorTracer; } #endif