cartobase  5.0.5
carto::RCObject Class Reference

Base class for reference counted objects (intrusive) More...

#include <cartobase/smart/rcptr.h>

Inheritance diagram for carto::RCObject:
Collaboration diagram for carto::RCObject:

Public Types

typedef int RefCounterType
 

Public Member Functions

 RCObject ()
 
 RCObject (const RCObject &)
 
RCObjectoperator= (const RCObject &)
 
virtual ~RCObject ()
 

Friends

template<class T >
class ref
 
template<class T >
class const_ref
 
template<class T >
class shared_ptr
 
class rc_ptr_trick
 

Detailed Description

Base class for reference counted objects (intrusive)

RCObject implements the reference counted object idiom. It allows the building of several Ref (see const_ref) with the same pointer.

Full description of the reference counted idiom in:

        Scott Meyers
        More Effective C++: 35 New Ways to Improve Your Programs and Designs
        Addison Wesley 1996
        Item 29

Full description of the observer/subject pattern in:

        Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides
        Design Patterns: Elements of Reusable Object-Oriented Software
        Addison Wesley 1995
        pp. 293-303
See also
rc_ptr weak_ptr

In some cases it can be necessary to build a Ref from a pointer to an already allocated object. This operation is allowed if and only if the object class derives from RCObject.

Here is an example of what must not be done. The following program build a Window class that has a static member named shownWindows which contains a list of all shown windows. The show() method must add a reference to this in the shown windows list. The program will compile but it will crash because the Window object will be destroyed several times. The problem is that the ref<Window> created in main() and the one created in Window::show() are in different scope. Therefore they have no way to know about eachother existence. Thus, each ref<Window> will use its own reference counter and both will destroy the Window upon destruction.

#include <iostream>
#include <list>
#include "rcptr.h"
using namespace carto;
class Window;
class Window
{
public:
Window();
~Window();
void show();
void hide();
private:
static list< ref<Window> > shownWindows;
};
list< ref<Window> > Window::shownWindows;
Window::Window()
{
cerr << "Construction of a Window" << endl;
}
Window::~Window()
{
cerr << "Destruction of a Window" << endl;
}
void Window::show()
{
shownWindows.push_back( this ); // Error, this window will be destroyed several times
}
void Window::hide()
{
shownWindows.remove( this ); // Error, this window will be destroyed several times
}
int main()
{
ref<Window> mainWindow = new Window;
mainWindow->show();
mainWindow->hide();
}

To avoid this problem, it is necessary to include the reference counter in the referenced object class (Window in our example). This is done by public inheritance of the class RCObject. Therefore, the right version of the program is slightly different from the bad one :

#include <iostream>
#include <list>
#include "rcptr.h"
using namespace carto;
class Window;
class Window : public virtual RCObject
{
public:
Window();
~Window();
void show();
void hide();
private:
static list< ref<Window> > shownWindows;
};
list< ref<Window> > Window::shownWindows;
Window::Window()
{
cerr << "Construction of a Window" << endl;
}
Window::~Window()
{
cerr << "Destruction of a Window" << endl;
}
void Window::show()
{
shownWindows.push_back( this );
}
void Window::hide()
{
shownWindows.remove( this );
}
int main()
{
ref<Window> mainWindow = new Window;
mainWindow->show();
mainWindow->hide();
}
Warning
It is strongly recommended to use virtual inheritance of RCObject to have exactly one reference counter in all derived classes.
When a class T is derived from RCObject, the constructors and destructors of ref<T> and const_ref<T> are redefined. This is done statically (at compile time). The Ref mecanism does not use any virtual function member.

Definition at line 106 of file rcptr.h.

Member Typedef Documentation

◆ RefCounterType

Definition at line 127 of file rcptr.h.

Constructor & Destructor Documentation

◆ RCObject() [1/2]

carto::RCObject::RCObject ( )
inline

Definition at line 135 of file rcptr.h.

◆ RCObject() [2/2]

carto::RCObject::RCObject ( const RCObject )
inline

Definition at line 137 of file rcptr.h.

◆ ~RCObject()

virtual carto::RCObject::~RCObject ( )
inlinevirtual

Definition at line 142 of file rcptr.h.

Member Function Documentation

◆ operator=()

RCObject& carto::RCObject::operator= ( const RCObject )
inline

Definition at line 140 of file rcptr.h.

Referenced by carto::MutexedObject::operator=().

Friends And Related Function Documentation

◆ const_ref

template<class T >
friend class const_ref
friend

Definition at line 112 of file rcptr.h.

◆ rc_ptr_trick

friend class rc_ptr_trick
friend

Definition at line 114 of file rcptr.h.

◆ ref

template<class T >
friend class ref
friend

Definition at line 111 of file rcptr.h.

◆ shared_ptr

template<class T >
friend class shared_ptr
friend

Definition at line 113 of file rcptr.h.


The documentation for this class was generated from the following file: