libshevek
src/refbase.hh
00001 /* refbase.hh - base class for using Glib::RefPtr
00002  * Copyright 2003 Bas Wijnen <wijnen@debian.org>
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation, either version 3 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #ifndef SHEVEK_REFBASE_HH
00019 #define SHEVEK_REFBASE_HH
00020 
00021 #include <sigc++/sigc++.h>
00022 #include <glibmm/refptr.h>
00023 
00024 namespace shevek
00025 {
00027   class refbase
00028   {
00029   public:
00031     template <typename _T> Glib::RefPtr <_T> cast_dynamic ()
00032     { return Glib::RefPtr <_T>::cast_dynamic (refptr_this <refbase> ()); }
00033   protected:
00035     refbase ();
00037     virtual ~refbase ();
00039 
00042     template <typename T> Glib::RefPtr <T> refptr_this ();
00043   private:
00044     // Not copyable
00045     refbase (refbase const &that);
00046     refbase &operator= (refbase const &that);
00047     // Reference functions, needed for Glib::RefPtr.
00048     virtual void reference ();
00049     virtual void unreference ();
00050     // Allow Glib::RefPtr to call the above.
00051     template <typename T> friend class Glib::RefPtr;
00052     // Reference count.
00053     unsigned m_refcount;
00054   };
00055 
00056   template <typename T>
00057   Glib::RefPtr <T> refbase::refptr_this ()
00058   {
00059     // This is a bit of a hack, but I don't see a way to solve it otherwise.
00060     // The idea is that members of refbase-derived classes need a refptr to
00061     // their this pointer, to give away.
00062     // The only usable constructor of RefPtr for that purpose is the one which
00063     // is meant for create ().  However, that does not increment the reference
00064     // counter.  So I do that by hand.
00065     reference ();
00066     return Glib::RefPtr <T> (dynamic_cast <T *> (this) );
00067   }
00068 }
00069 
00070 #endif