При использовании библиотеки coin3d интенсивно используется динамическое создание объектов, при этом запрещено непосредственное объектов посредством вызова деструктора, т.е. создание объектов графа-сцены в стеке невозможно.Удаление объектов происходит аналогично COM-объектам. В каждом объекта реализован интрузивный счётчик ссылок, при каждом добавлении объекта в граф-сцену счётчик ссылок увеличивается, при изымании объекта или удалении граф-сцены счётчик уменьшается. При обнулении счётчика объект удаляется.Это создаёт небольшую проблему: велика возможность утечек памяти, если в процессе построения граф-сцены случится что-то неожиданное. Чтобы хоть как-то уменьшить эту проблему я написал аналог класса std::auto_ptr, но для объектов граф-сцены.Для упрощения создания объектов, не требуется явная передача указателя на динамически созданный объект. По умолчанию, автоматически конструируется объект заданного типа. При явной передаче указателя на управление, указатель может быть указанного типа или любого дочернего типа. SoAutoPtr.h 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#pragma once
/** auto ptr
Пример использования:
SoAutoPtr<SoSeparator> sep;
SoAutoPtr<SoCube> cube;
sep->addChild( cube );
*/
template< class T>
class SoAutoPtr
{
public:
/*explicit*/ SoAutoPtr( T * ptr = 0 )
: _ptr(ptr)
{
if( !_ptr )
_ptr = new T;
_ptr->ref();
}
SoAutoPtr( const SoAutoPtr & rhs )
{
_ptr = rhs._ptr;
_ptr->ref();
}
SoAutoPtr & operator = ( const SoAutoPtr & rhs )
{
if( _ptr )
_ptr->unref();
_ptr = rhs._ptr;
_ptr->ref();
return *this;
}
~SoAutoPtr()
{
if( _ptr )
_ptr->unref();
}
T * operator -> () const
{
return _ptr;
}
operator T* ()
{
return _ptr;
}
T* Release()
{
_ptr->unrefNoDelete();
T* result = _ptr;
_ptr = 0;
return result;
}
private:
T * _ptr;
};
|