/////////////////////////////////////////////////////////////// // CompRefCount.h - Demonstrate Reference Counting Helpers // // // // Jim Fawcett, CSE775 - Distributed Objects, Spring 2014 // /////////////////////////////////////////////////////////////// #include #include #include // C++11 ///////////////////////////////////////////////////////////////////////// // Flexible Interface - define results and zero or more arguments // in template declaration template // C++11 variadic template struct ISearchComp { virtual ~ISearchComp() {}; // Zack was right - you do need this virtual R search(A...) = 0; // C++11 variadic function virtual ISearchComp* AddRef() = 0; virtual void Release() = 0; virtual void Verbose(bool pred=true) = 0; }; ///////////////////////////////////////////////////////////////////////// // Reference counting wrapper - expects instance to reside on heap template class AbstractRefCount : public T { public: AbstractRefCount() { refCnt = 1; } T* AddRef() { ++refCnt; return this; } void Release() { if (--refCnt == 0) delete this; } ~AbstractRefCount() { if (verbose_) std::cout << "\n destroying Reference Counted Instance"; } protected: bool verbose_ = false; private: std::atomic refCnt; // Reference Counting will be thread safe }; ///////////////////////////////////////////////////////////////////////// // Our specific Reference Counted Component //typedef std::vector Result; //typedef std::string Path; //typedef std::vector Patterns; using Result = std::vector; // C++11 aliases using Path = std::string; using Patterns = std::vector; using ISearchComponent = ISearchComp; class SearchComp : public AbstractRefCount { public: SearchComp() : AbstractRefCount() {}; Result search(const Path& path, const Patterns& patterns); void Verbose(bool pred=true) { verbose_ = pred; } ~SearchComp(); }; ///////////////////////////////////////////////////////////////////////// // Note: // If you Define a search interface, as done above, then // define another with different arguments, you don't break // clients of the old interface. You've defined a new // interface type and both the clients of the old and the new // still work.