/////////////////////////////////////////////////////////////// // boltIns.cpp - Add functionality to a class // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2005 // /////////////////////////////////////////////////////////////// #include #include #include #include "boltIns.h" #ifdef TEST_BOLTINS /////////////////////////////////////////////////// // this global object causes newlines to be emitted // after destroying local objects and leaving main struct FinalNewLines { ~FinalNewLines() { std::cout << "\n\n"; } } global; /////////////////////////////////////////////////// // test structure struct Stuff { int x; double y; char z; }; /////////////////////////////////////////////////// // test classes for reference counting wrapper class Base { public: Base() {} virtual ~Base() {} virtual std::string say() { return "I'm a Base type"; } }; typedef refCounted CountedBase; class CountedDerived : public CountedBase { public: CountedDerived() {} virtual std::string say() { return "I'm a Derived type"; } }; /////////////////////////////////////////////////// // test classes for inherited reference counting class iBase : public irefCounted { public: iBase() {} virtual ~iBase() {} virtual std::string say() { return "I'm a Base type"; } }; class iDerived : public iBase { public: iDerived() {} virtual std::string say() { return "I'm a Derived type"; } }; // /////////////////////////////////////////////////// // test stub void main() { std::cout << "\n SmartPtr Boltins" << "\n ==================\n"; ///////////////////////////////////////////////// std::cout << "\n creating a smart pointer to wrapped double:\n"; ///////////////////////////////////////////////// typedef wrapped wDouble; refCounted< wDouble > rcd = 3.1415927; smartPtr< refCounted< wDouble > > spDouble1(&rcd); std::cout << "\n value pointed to = " << *spDouble1 << std::endl; ///////////////////////////////////////////////// std::cout << "\n after copy construction of another smart pointer:" << std::endl; ///////////////////////////////////////////////// smartPtr< refCounted< wDouble > > spDouble2 = spDouble1; std::cout << "\n value pointed to = " << *spDouble2 << std::endl; ///////////////////////////////////////////////// std::cout << "\n after changing value via the new pointer:" << std::endl; ///////////////////////////////////////////////// *spDouble2 = -3.5; std::cout << "\n value pointed to = " << *spDouble2 << std::endl; std::cout << "\n value pointed to by the original pointer:\n"; std::cout << "\n value pointed to = " << *spDouble1 << std::endl; ///////////////////////////////////////////////// std::cout << "\n creating a smart pointer to " << "struct { int; double; char; } myStuff\n"; ///////////////////////////////////////////////// Stuff myStuff = { -2, 3.5, 'Z' }; refCounted rcs = myStuff; smartPtr< refCounted > spS1(&rcs); std::cout << "\n char selected from myStuff = " << spS1->z << std::endl; ///////////////////////////////////////////////// std::cout << "\n after assignment of old pointer to new pointer\n"; ///////////////////////////////////////////////// smartPtr < refCounted > spS2; spS2 = spS1; std::cout << "\n char selected from myStuff = " << spS2->z << std::endl; ///////////////////////////////////////////////// std::cout << "\n after changing value via the new pointer:\n"; ///////////////////////////////////////////////// spS2->z = 'a'; std::cout << "\n char selected from myStuff = " << spS2->z << std::endl; std::cout << "\n value pointed to by the original pointer:\n"; std::cout << "\n char selected from myStuff = " << spS1->z << std::endl; // ///////////////////////////////////////////////// std::cout << "\n Testing Polymorphic Operations " << "with wrapper reference counting:\n"; ///////////////////////////////////////////////// ///////////////////////////////////////////////// // Test reference counting wrapper // test set with copy of existing instance refCounted* pRCB = new refCounted; smartPtr spBase0; spBase0.set(pRCB); std::cout << "\n " << spBase0->say().c_str(); // test set with new instance smartPtr spBase1; spBase1.set(); std::cout << "\n " << spBase1->say().c_str(); // test polymorphic operation smartPtr spBase2; spBase2.set(); std::cout << "\n " << spBase2->say().c_str(); std::cout << std::endl; // test copy construction smartPtr spBase3 = spBase2; std::cout << "\n " << spBase2->say().c_str(); std::cout << std::endl; // test assignment spBase3 = spBase2; std::cout << "\n " << spBase2->say().c_str(); std::cout << std::endl; ///////////////////////////////////////////////// std::cout << "\n Testing Containment of Smart Pointers:\n"; ///////////////////////////////////////////////// typedef std::vector< smartPtr > VecSmtPtr; VecSmtPtr vsp; vsp.push_back(spBase0); vsp.push_back(spBase1); vsp.push_back(spBase2); VecSmtPtr::iterator it; for(it=vsp.begin(); it!=vsp.end(); ++it) std::cout << "\n " << (*it)->say().c_str(); std::cout << std::endl; // Calling release does no harm spBase2->release(); // ///////////////////////////////////////////////// std::cout << "\n Testing Polymorphic Operations " << "with inherited reference counting:\n"; ///////////////////////////////////////////////// // test set with copy of existing instance iBase* pIB = new iBase; smartPtr spIBase0; spIBase0.set(pIB); std::cout << "\n " << spIBase0->say().c_str(); // test set with new instance smartPtr spIBase1; spIBase1.set(); std::cout << "\n " << spIBase1->say().c_str(); // test polymorphic operation smartPtr spIBase2; spIBase2.set(); std::cout << "\n " << spIBase2->say().c_str(); std::cout << std::endl; // test copy construction smartPtr spIBase3 = spIBase2; std::cout << "\n " << spIBase2->say().c_str(); std::cout << std::endl; // test assignment spIBase3 = spIBase2; std::cout << "\n " << spIBase2->say().c_str(); std::cout << std::endl; ///////////////////////////////////////////////// std::cout << "\n Testing Containment of Smart Pointers:\n"; ///////////////////////////////////////////////// typedef std::vector< smartPtr > VecSmtPtr2; VecSmtPtr2 vsp2; vsp2.push_back(spIBase0); vsp2.push_back(spIBase1); vsp2.push_back(spIBase2); VecSmtPtr2::iterator it2; for(it2=vsp2.begin(); it2!=vsp2.end(); ++it2) std::cout << "\n " << (*it2)->say().c_str(); std::cout << std::endl; // Calling release does no harm spIBase2->release(); ///////////////////////////////////////////////// std::cout << "\n Testing acquizition of base and derived objects:\n"; ///////////////////////////////////////////////// iBase* pIB2 = new iBase; smartPtr spb(pIB2); // using template member ctor std::cout << "\n " << spb->say().c_str(); iDerived* pID2 = new iDerived; smartPtr spd(pID2); // using template member ctor again std::cout << "\n " << spd->say().c_str() << std::endl; ///////////////////////////////////////////////// std::cout << "\n pushing these into vector:\n"; ///////////////////////////////////////////////// VecSmtPtr2 vsp3; vsp3.push_back(spb); vsp3.push_back(spd); for(it2=vsp3.begin(); it2!=vsp3.end(); ++it2) std::cout << "\n " << (*it2)->say().c_str(); std::cout << "\n\n"; } #endif