Sponsored Link •
|
Summary
The boost::any type is a very important type in that it can hold any object which has a copy-constructor. However if you don't want to hold a copy of the value you can instead refer to the object using the ootl::any_ptr type.
Advertisement
|
My ootl::any_ptr class can point to any object with a copy-constructor, and provides the following public functions:
void Delete(); any_ptr Clone() const; const type_info& GetType(); template<typename ValueType> ValueType* PtrCast();The implementation is below:
// this class can point to any copy-constructible value_type // and let you clone or delete it safely class any_ptr { public: // forward declarations template <class T> struct functions; template <class T> any_ptr(T* x) : m_a(x), m_t(&functions<T>::table) {} any_ptr() : m_a(NULL), m_t(NULL) {} void Delete() { assert(m_a != NULL); m_t->Delete(m_a); m_a = NULL; } any_ptr Clone() const { any_ptr o(*this); o.m_a = m_t->Clone(m_a); return o; } const std::type_info& GetType() const { return m_t->GetType(m_a); } template<typename ValueType> ValueType* PtrCast() { if (!(typeid(ValueType) == GetType())) { throw BadObjectCast(); } return static_cast<ValueType*>(m_a); } // Function table type // order is important, must match all other lists of functions struct table { void (*Delete)(void*); const std::type_info& (*GetType)(void*); void* (*Clone)(void*); }; // For a given referenced type T, generates functions for the // function table and a static instance of the table. template<class T> struct functions { static typename any_ptr::table table; static void Delete(void* p) { delete static_cast<T*>(p); } static const std::type_info& GetType(void* p) { return typeid(T); } static void* Clone(void* p) { return new T(*static_cast<T*>(p)); } }; private: void* m_a; table* m_t; }; template<class T> typename any_ptr::table any_ptr::functions<T>::table = { &any_ptr::template functions<T>::Delete ,&any_ptr::template functions<T>::GetType ,&any_ptr::template functions<T>::Clone };Those paying close attention to my work, and not intimidated by complex template code, may realize that lately I have been riding in to town with the same horse, but painting it different colors. What I mean to say is that the basic idea is always the same, create a function pointer table at compile time for every assignment or copy-construction to a different type. Each generated function in the table is responsible for casting the internal pointer to the appropriate type. Hopefully all this makes some sense, and industrious readers can contribute some interesting applications of this class and/or technique.
Have an opinion? Readers have already posted 1 comment about this weblog entry. Why not add yours?
If you'd like to be notified whenever Christopher Diggins adds a new entry to his weblog, subscribe to his RSS feed.
Christopher Diggins is a software developer and freelance writer. Christopher loves programming, but is eternally frustrated by the shortcomings of modern programming languages. As would any reasonable person in his shoes, he decided to quit his day job to write his own ( www.heron-language.com ). Christopher is the co-author of the C++ Cookbook from O'Reilly. Christopher can be reached through his home page at www.cdiggins.com. |
Sponsored Links
|