#ifndef BOLTINS_H #define BOLTINS_H /////////////////////////////////////////////////////////////// // boltIns.h - Add functionality to a class // // ver 2.1 // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2005 // /////////////////////////////////////////////////////////////// // Boltins were described in detail in: // // "Imperfect C++", Matthew Wilson, Addison-Wesley, 2005 // /////////////////////////////////////////////////////////////// /* * Boltins are template classes that: * 1. derive publicaly from their first template parameter * 2. may add virtual methods or override base virtual methods * if the base class is polymorphic * 3. may increase the size of base by adding data members * and/or new virtual methods and/or new non-empty bases */ /////////////////////////////////////////////////// // smartPtr - not a boltin (those are below) /////////////////////////////////////////////////// template class smartPtr { public: smartPtr() : m_pTr(0) {} ///////////////////////////////// // template member template smartPtr(U* pU) : m_pTr(new U(*pU)) { m_pTr->addRef(); } smartPtr(const smartPtr& sp) : m_pTr(sp.m_pTr) { if(m_pTr) m_pTr->addRef(); } virtual ~smartPtr() { if(m_pTr) m_pTr->release(); } T& operator*() { return *m_pTr; } T* operator->() { return m_pTr; } ///////////////////////////////// // template member template void set(U* pU = 0); smartPtr& operator=(const smartPtr& sp); protected: T* m_pTr; }; // /////////////////////////////////////////// // template member definition template template // note second template void smartPtr::set(U* pU = 0) { if(m_pTr) m_pTr->release(); if(pU) m_pTr = new U(*pU); else m_pTr = new U; m_pTr->addRef(); } template smartPtr& smartPtr::operator=(const smartPtr& sp) { if(this == &sp) return *this; if(m_pTr) m_pTr->release(); m_pTr = sp.m_pTr; m_pTr->addRef(); return *this; } // /////////////////////////////////////////////////// // reference counted object boltin wrapper /////////////////////////////////////////////////// // - adds reference counting to an object that // needs it so as to be smartPtr managed /////////////////////////////////////////////////// template class refCounted : public T { public: refCounted() : m_count(0) {} refCounted(const T& t) : m_count(0), T(t) {} virtual ~refCounted() {} refCounted& operator=(const T& t) { static_cast(*this) = t; return *this; } void addRef() { ++m_count; } void release() { if(--m_count == 0) { delete this; #ifdef TEST_BOLTINS #include std::cout << "\n destroying ref counted object"; #endif } } protected: unsigned m_count; }; // /////////////////////////////////////////////////// // reference counted object base /////////////////////////////////////////////////// // - adds reference counting to an object that // needs it so as to be smartPtr managed /////////////////////////////////////////////////// class irefCounted { public: irefCounted() : m_count(0) {} virtual ~irefCounted() {} void addRef() { ++m_count; } void release() { if(--m_count == 0) { delete this; #ifdef TEST_BOLTINS #include std::cout << "\n destroying ref counted object"; #endif } } protected: unsigned m_count; }; /////////////////////////////////////////////////// // Almost boltin wrapper for non-class types /////////////////////////////////////////////////// // - makes a class that behaves like // an original primitive type // - can't inherit from T since primitive types // are not class types /////////////////////////////////////////////////// template class wrapped // can't inherit from T { public: wrapped() : m_T(0) {} wrapped(const wrapped& w) : m_T(w.m_T) {} wrapped(T t) : m_T(t) {} wrapped& operator=(T t) { m_T = t; } operator T () { return m_T; } private: T m_T; }; #endif