Re: [gtkmm] Glib::RefPtr construction
- From: Michael Johnson <michaelj maine rr com>
- To: gtkmm mailing list <gtkmm-list gnome org>
- Subject: Re: [gtkmm] Glib::RefPtr construction
- Date: Tue, 07 Jan 2003 19:50:39 -0500
Murray Cumming wrote:
On Tue, 2003-01-07 at 22:08, Michael Johnson wrote:
In reading through the source for Glib::RefPtr I note that the constructor
RefPtr<T_CppObject>::RefPtr(T_CppObject* pCppObject)
Does not increase the reference count of the referenced object, though
all other means of assigning a value to a RefPtr (including the
assignment operator that takes a pointer) do increase the reference
count. Is this intentional, or is it an accidental omission?
The pCppObject is normally created with a refcount of 1, and the final
RefPtr<> destructor unrefs it to 0, causing pCppObject to be deleted.
I realize I am a newcomer to the list, and I do not wish to step on any toes,
so please consider the following discussion in the spirit in which it is
offered, as constructive discourse. In my professional capacity, I have in
the past implemented a large, complex system of classes that used smart-pointer
management of reference-counted objects and as a result I have learned some
things from practical experience.
In my opinion, the behavior described above appears to be dangerous and error-prone.
Especially in light of the fact that SigC::Object, which is perfectly capable
of being managed by RefPtr, does not behave this way. It starts with a reference
count of zero. Consider the following samples of code:
Glib::RefPtr<Foo> rpFoo;
return (rpFoo = new Foo());
Versus:
return Glib::RefPtr<Foo>(new Foo());
or even:
Glib::RefPtr<Foo> rpFoo = new Foo();
return rpFoo;
These three code examples, which one would reasonably expect to behave the
same, in fact yield different results. The first case will result in a reference
count that is one higher than the other two cases. This is non-intuitive.
It also seems to me that constructing the object with a reference count of
1 is conceptually incorrect. At the time of construction, no "reference"
to the object exists, therefore the reference count should be zero. There
will not in fact be a reference to the object until a RefPtr (which embodies
the reference) is constructed with or assigned a pointer to the object. There
is also the question of appropriate assignment of roles and responsibilities.
A reference-counted object has a reference count, but does not itself manage
that reference count. It merely provides a means for other objects (which
embody references) to manage the reference count. It is the role of the reference
class to manage the reference count of objects being referenced. It makes
sense then that any method of the reference class that changes the value
of the reference should participate in the management of the reference count.
Looking at Glib::ObjectBase, there is probably no reason why its overrides
of reference() and unreference() could not in turn call the SigC::ObjectBase
reference() and unreference() methods. By default, those methods will not
delete the object when the reference count goes to zero. This only happens
if the set_manage() method is called, so it is normally safe to construct
objects derived from Glib::ObjectBase on the stack. It then becomes simpler
for classes derived from Glib::ObjectBase to enable lifetime management by
reference counting. They don't have to override reference() and unreference(),
they merely need to invoke set_manage() in their constructor. Nor do they
need to (redundantly, because it is already being done by SigC::ObjectBase)
include a reference-count data member.
This has advantages. Consider the possibility of reference-counted objects
being shared across multiple threads. Overlapping calls to the reference()
and unreference() methods from different threads must be guarded against.
The simplest way to do this is to use an atomic counter so that increment
or decrement of the counter is thread-safe. If many classes in gtkmm re-implement
reference counting, then all of those classes must be changed in order to
make gtkmm thread-safe. If those same classes used the underlying reference
counting in SigC::ObjectBase then only SigC::ObjectBase would need to be
made thread-safe in order for all classes derived from it to be in turn thread-safe.
Does anyone else have any thoughts on this?
..mj
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]