///////////////////////////////////////////////////////////////////// // testSmartPtr.cpp - Demonstrates basic functionality of // // Loki::SmartPtr // // // // Loki is a template-based library developed by the author of: // // Modern C++ Design, Andrei Alexandrescu, Addison-Wesley, 2001 // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2004 // ///////////////////////////////////////////////////////////////////// // Required Files: // // TestSmartPtr.cpp, SmartPtr.h, Singleton.h, Singleton.cpp, // // SmallObj.h, SmallObj.cpp, static_check.h, Threads.h, // // TypeManip.h // ///////////////////////////////////////////////////////////////////// // // template // < // typename T, // class OwnershipPolicy = RefCounted, // class ConversionPolicy = DisallowConversion, // class CheckingPolicy = AssertCheck, // class StoragePolicy = DefaultSPStorage // > // class SmartPtr; // // OwnershipPolicies: // RefCounted - default // RefCountedMT - thread safe // COMRefCounted - Adapts COM reference counting // RefLinked - ?? // DestructiveCopy - transfers ownership // NoCopy - disallows copying // // ConversionPolicies: // AllowConversion - allows conversion from SmartPtr to Pointee Type // DisallowConversion - does not allow conversion // // CheckingPolicies: // NoCheck - does not check before dereference // AssertCheck - asserts on null pointer // AssertCheckStrict - asserts on null pointer dereference, initialization // RejectNullStatic - ?? // RejectNullStrict - ?? // // StoragePolicy: // DefaultSPStorage - default storage #include #include #include #include "SmartPtr.h" using namespace Loki; // ///////////////////////////////////////////////////////////////////// // Wrapper that announces construction and destruction // template class WrappingAnnunciator { public: WrappingAnnunciator(const T& t); WrappingAnnunciator(const WrappingAnnunciator& wa); ~WrappingAnnunciator(); WrappingAnnunciator* Clone(); T& value(); private: T _t; }; template WrappingAnnunciator::WrappingAnnunciator(const T&t) : _t(t) { std::cout << "\n created"; } template WrappingAnnunciator::WrappingAnnunciator(const WrappingAnnunciator& wa) : _t(wa._t) { std::cout << "\n copied"; } template WrappingAnnunciator::~WrappingAnnunciator() { std::cout << "\n destroyed"; } template T& WrappingAnnunciator::value() { return _t; } template WrappingAnnunciator* WrappingAnnunciator::Clone() { return new WrappingAnnunciator(*this); } // ///////////////////////////////////////////////////////////////////// // Demonstration // Experiment with the following: // 1. run with default Ownership ==> reference counting // 2. run with Deep Copy Ownership // 3. comment out the vec.reserve(20) to see LOTS of copies // due to reallocations during push_backs void main() { std::cout << "\n Testing Loki::SmartPtr " << "\n ===============================\n"; typedef WrappingAnnunciator WA; /////////////////////////////////////////////////////////////////// // Deep Copy Ownership Policy // //typedef SmartPtr< WA, WrapTemplate > SP; // deep copy //std::cout << "\n using SmartPointer with DeepCopy\n"; /////////////////////////////////////////////////////////////////// // Reference Counted Ownership Policy (default) // typedef SmartPtr< WA > SP; // reference counted std::cout << "\n using SmartPointer with Reference Counting\n"; std::string strArray[] = { "zebra", "platypus", "arrdvark", "condor" }; std::cout << "\n" <<"\n Creating vector of SmartPtrs " << "\n ------------------------------"; std::vector< SP > vec; vec.reserve(20); for(int i=0; i<4; ++i) { std::cout << "\n create SmartPtr: "; SP sp(new WA(strArray[i])); std::cout << "\n push onto vector: "; vec.push_back(sp); } std::cout << std::endl; for(int i=0; i<4; ++i) std::cout << "\n " << (*vec[i]).value(); std::cout << "\n" << "\n Copying vector of SmartPtrs " << "\n -----------------------------"; std::vector< SP > vecCopy = vec; std::cout << std::endl; for(int i=0; i<4; ++i) std::cout << "\n " << (*vecCopy[i]).value(); std::cout << std::endl; }