[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    KSharedPtr
From:       Waldo Bastian <bastian () ens ! ascom ! ch>
Date:       1999-07-12 13:49:19
[Download RAW message or body]

Hiya,

Yesterday I had some discussion with Simon about KSharedPtr.
IMHO the way KSharedPtr currently behaves is dangerous: it
is easy to create bugs. Simon and I had some different
opinions about a possible solution. I will first outline 
the problem and then propose the solution I like most.

The problem
===========

Currently KSharedPtr can be used as a refcounting pointer
to objects derived from QShared.

If we have something like:
  class X : public QShared { ... }

Then we can have declare a recounting pointer 'ptr' like:
  KSharedPtr<X> ptr;

Class X does maintain a refcounter (QShared to be more precise).

KSharedPtr has two constructors:

  KSharedPtr<X>( const KSharedPtr<X> &x) // Increases refcount
  KSharedPtr<X>( X *x) // Does not increase refcount 

The current behaviour is as follow:

  X x = X(); // x has a refcount of 1
  KSharedPtr<X> ptr = x; // x has still a refcount of 1
  KSharedPtr<X> ptr2 = ptr; // refcount of x increases: it becomes 2

The problem is that code like:

  X x = X(); // x has a refcount of 1
  KSharedPtr<X> ptr = x; // x has still a refcount of 1
  KSharedPtr<X> ptr2 = x; // x has still a refcount of 1

Leads to a crash when both ptr and ptr2 get destructed.

Also code like:

  KSharedPtr<X> ptr3 = (X *) ptr; 

Will lead to an incorrect refcount.

The solution
============

Don't use QShared but use KShared.
A KShared object starts with a refcount of 0.

Both 
  KSharedPtr<X>( const KSharedPtr<X> &x) 
as well as
  KSharedPtr<X>( X *x) 
should increase the refcount.

The behaviour will then be like:

  X x = X(); // x has a refcount of 0
  KSharedPtr<X> ptr = x; // refcount of x increases: it becomes 1
  KSharedPtr<X> ptr2 = ptr; // refcount of x increases: it becomes 2

And with code like:

  X x = X(); // x has a refcount of 0
  KSharedPtr<X> ptr = x; //refcount of x increases: it becomes 1
  KSharedPtr<X> ptr2 = x; //refcount of x increases: it becomes 2

And will work correctly.

Also code like:

  KSharedPtr<X> ptr3 = (X *) ptr; 

Will now correctly update the refCount.

Proposal for KShared:

class KShared
{
   KShared() : count(0) { }
   void KShared::ref() { count++ };
   void KShared::unref() { if (!--count) delete this; }
protected:
   virtual ~KShared() { }
   int count;
}  

Cheers,
Waldo








-- 
The "gui" in "Penguin" is pronounced "K-D-E"

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic