Здравствуйте, Аноним, Вы писали:
А>Никто не подскажет, где взять сабж?
А>Синхронизация не нужна. Нужен неинтрузивный подсчет ссылок на объекты.
А>Скажем, нужен boost::shared_ptr с отключенной синхронизацией. или способ отключить ее без хирургического вмешательства.
Попробуй вот это. Автор я, сам с удовольствием пользуюсь. Класс используется в реальном коммерческом проекте.
Буду благодарен за любую конструктивную критику.
////////////////////////////////////////////////////////////////////////////////////
// countable.h
//
// Author: Vitaliy Ivanchenko, <vtal@ukr.net>
// Copyright (c) Kiev, 2005
//
// Implementation of class that stores a pointer to allocated object of type T.
// The stored pointer must either be NULL or designate an object allocated by a new
// expression.
//
////////////////////////////////////////////////////////////////////////////////////
//
// History
// _________________________________________________________________________________
//
// [15.07.2005]
// _countable class was implemented.
// -----------------------------------------------------------------------
// [19.07.2005]
// Bugs were fixed in assignment operator:
// 1) Release of the stored object performed incorrectly before copying.
// 2) Memory used for reference counter was not free if the object is
// the same but counters are different.
// -----------------------------------------------------------------------
// [22.10.2005]
// Bug was fixed in assignment operator:
// Memory used for reference counter was not release if pointer to stored
// object equals NULL.
// -----------------------------------------------------------------------
// [22.10.2005]
// Assignment operator of pointer to countable object was implemented.
// -----------------------------------------------------------------------
//
#if !defined(__COUNTABLE_H_A1ECF5CC_FDB0_4f27_9D50_7F75C07AF8F4_INCLUDED_)
#define __COUNTABLE_H_A1ECF5CC_FDB0_4f27_9D50_7F75C07AF8F4_INCLUDED_
#include <assert.h>
template <typename T> class _countable
{
public:
typedef T element_type;
//
// Default constructor
//
explicit _countable(T * p = 0) throw() : m_pObj(p), m_pRef(NULL)
{
m_pRef = new long(0L);
_increment();
}
//
// Copying constructor
//
_countable(const _countable<T>& Y) throw() : m_pObj(Y.m_pObj), m_pRef(Y.m_pRef)
{
_increment();
}
//
// Assignment operators
//
_countable<T>& operator=(const _countable<T>& Y) throw()
{
if (this != &Y)
{
if (m_pObj != Y.get())
{
_decrement();
m_pObj = Y.get();
m_pRef = Y.m_pRef;
_increment();
}
else if (m_pRef != Y.m_pRef)
{
//
// Usage counter (i.e. value of *m_pRef) must be equal to 1 always here;
// otherwise we have unsolvable problem caused by incorrect _countable usage.
//
assert(1 == *m_pRef);
if (1 == *m_pRef) delete m_pRef;
m_pRef = Y.m_pRef;
_increment();
}
}
return (*this);
}
_countable<T>& operator=(typename T * pT) throw()
{
if( m_pObj != pT )
{
_decrement();
m_pRef = new long(0L);
m_pObj = pT;
_increment();
}
return (*this);
}
//
// Destructor
//
virtual ~_countable()
{
_decrement();
}
T& operator*() const throw()
{
return (*get());
}
T *operator->() const throw()
{
return (get());
}
T *get() const throw()
{
return m_pObj;
}
long _increment()
{
return ++(*m_pRef);
}
long _decrement()
{
if (--(*m_pRef)) return (*m_pRef);
//
// Do something useful when counter reaches 0 (e.g. destroy object)
//
delete m_pObj;
delete m_pRef;
return 0;
}
private:
T * m_pObj; // storage object pointer
long * m_pRef; // reference counter
};
#endif //__COUNTABLE_H_A1ECF5CC_FDB0_4f27_9D50_7F75C07AF8F4_INCLUDED_