Re: [C++]Use Glib::RefPtr<> with my own classes ?



On Fri, 30 Jul 2010 18:21:04 +0200
Aurélien Ansel <camumus gmail com> wrote:
> I try to use Glib::RefPtr<> with my own classes.
> I have seen in the docs that Glib::RefPtr is the smart pointers for
> the Glib::Object subclasses, subclasses that wraps C functionalities
> of the Glib, is it ?
> 
> I have developped my main class in order to subclass it with my other
> classes :
> 
> class Referencable
> {
> public:
>     void reference();
>     void unreference();
> 
> protected:
>     Referencable():_ref_counter(1) {}
>     virtual ~Referencable() {}
> 
> private:
>     unsigned long long _ref_counter;
> };
> 
> 
> the 2 main methods :
> 
> void Referencable::reference() {
>     ++_ref_counter;
> }
> 
> void Referencable::unreference() {
>     --_ref_counter;
>     if (_ref_counter == 0)
>         delete this;
> }
> 
> 
> I have tested it, that seems to work, but after developped many
> subclasses with it, i had some problems with invalids Glib::RefPtr
> that are destroyed "too soon".
> 
> My questions are : is it possible to use Glib::RefPtr<> with classes
> that aren't from Glib C ?
> If yes, someone have an idea what is wrong with my code ?

It is possible, if objects of those classes are created with a reference
count of 1 and delete themselves when it reaches 0, as yours do, and
have reference() and unreference() methods, as yours also do.

The problem with using RefPtr with non-GObjects, however, is the "if it
is created with a reference count of 1": RefPtr is constrained to do
it this way because new GObjects begin with a reference count of 1.
This is unlike conventional intrusive pointers, which expect objects to
be created with a reference count of 0, and means that the constructor
taking a pointer does not increment the reference count. This means in
turn that you cannot pass by pointer an object which is already owned
by another RefPtr: you can only pass it by RefPtr (the copy constructor
and assignment operator of which do increment the reference count).

In short, RefPtr will only work in your scenario if you treat it like
a shared pointer: the constructor taking a pointer must only take a
newly created object which has never seen another RefPtr.

This is probably what you are doing wrong.

It is trivial to make a conventional intrusive pointer, which expects
new objects to have a count of 0 and which does increment the reference
count in the constructor taking a pointer.  I suggest you do it that
way.

Chris




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]