Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Организация подсчета ссылок для умного указателя, Как организовать подсчет ссылок 
V
    Опции темы
azesmcar
Дата 23.11.2007, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Добрый вечер,

Пишу умный указатель, столкнулся с такой вот проблемой.

К примеру
Код

template <class _T>
class smart_ptr
{
public:
    smart_ptr(_T* ptr)
    {
        object = ptr;

        ++ref_count;
    }

    ~smart_ptr()
    {
        --ref_count;
        if (ref_count == 0)
            delete ptr;
    }
private:
    smart_ptr(const smart_ptr& rhl);
    smart_ptr& operator = (const smart_ptr& rhl);
    _T* object;

    static int ref_count;
};


(это далеко не идеальный код умного указателя, просто для примера написал)

и...возьмем к примеру такой вот код в функции main
Код

smart_ptr mc_ptr1(new mc(1)); //представим что есть у нас такой класс mc
smart_ptr mc_ptr2(new mc(2));

в этом случае наш счетчик ссылок будет иметь значение 2, что неверно, ведь mc_ptr1 и mc_ptr2 разные обьекты..несмотря на то что типы у них одинаковые. Следовательно подсчет ссылок организован нерверно. Первое решение пришедшее на ум это использовать std::map. 
Но мне оно не кажеться самым лучшим, почему то не покидает чувство что есть вариант получше. Попробовал посмотреть как реализован boost::shared_ptr, но boost как оказался не блещет обилием понятного кода и решил что лучше спросить у тех кто сталкивался, чем копаться в классах sp_counted_base, sp_counted_impl, sp_counted_base, weak_count итд...

Заранее спасибо
PM   Вверх
MAKCim
Дата 24.11.2007, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Код

template <class _T>
class smart_ptr
{
public:
    smart_ptr(_T* ptr)
    {
        object = ptr;
        ref_count = new int(1);
    }

    smart_ptr(const smart_ptr<T>& ref) {
        ref_count = &++*ref.ref.count;
        object = ref.object;
    }

    smart_ptr<T>& operator=(const smart_ptr<T>& ref) {
        destroy();
        ref_count = &++*ref.ref_count;
        object = ref.object;
    }

    ~smart_ptr()
    {
        destroy();
    }
private:
    void destroy() {
        if (!--*ref_count) {
            delete ref_count;
            delete object;
        }
    }

    smart_ptr(const smart_ptr& rhl);
    smart_ptr& operator = (const smart_ptr& rhl);
    _T* object;
    int * ref_count;
};


Это сообщение отредактировал(а) MAKCim - 24.11.2007, 00:02


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 24.11.2007, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Есть несколько способ подсчитывать ссылки.
1. Построение связного списка из уиных указателей(т.о., когда список пуст, память удаляется).
2. Создание динамического счётчика.

Вот простой пример для 2-го случая:
Код

class rc
{
    rc()
        : pc(new int(1))
    { }
    rc(const rc &rhs)
        : pc(rhs.pc)
    {
        ++(*pc);
    }
    rc &operator =(const rc &rhs)
    {
         finalize();
         pc = rhs.pc;
         ++(*pc);
         
         return *this;
    }

    ~rc()
    { finalize(); }
    
    bool last()
    { return *rc == 1; }

private:
    void finalize()
    {
        if (--(*pc) > 0)
            pc.release();
    }

    std::auto_ptr< int > pc;
};

template< typename T >
class sp
{
public:
    sp(T *p)
        : p(p)
    { }
    
    template< class U >
    sp(const sp< U > &rhs)
        : c(rhs.c), p(rhs.p)
    { }
    
    template< class U >
    sp &operator =(const sp< U > &rhs)
    {
        if (c.last())
            delete p;
        
        c = rhs.c;
        p = rhs.p;
    }
    
    ~sp()
    {
        if (c.last())
            delete p;
    }
    
    T *get() const
    { return p; }
    
    // и пр. ф-ции, имитирующие работу указателя
private:
    rc c;
    T *p;
};


ps. Писал здесь, мог облажаться...

Добавлено через 1 минуту и 27 секунд
У MAKCimа код короче, а у меня более повторно используемый smile.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
azesmcar
Дата 24.11.2007, 00:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата

Код

ref_count = &++*ref.ref.count;



ааааа smile вот оно что
Почему то все время на static тянуло smile
остальное уже сам додумаю.

Всем спасибо

PM   Вверх
JackYF
Дата 24.11.2007, 00:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(azesmcar @  24.11.2007,  00:14 Найти цитируемый пост)
Всем спасибо

тему-то закрой ;)


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
UnrealMan
Дата 24.11.2007, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(archimed7592 @  24.11.2007,  00:03 Найти цитируемый пост)
У MAKCimа код короче, а у меня более повторно используемый 

У вас обоих не учтено самоприсваивание.
PM MAIL   Вверх
archimed7592
Дата 24.11.2007, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(UnrealMan @  24.11.2007,  15:21 Найти цитируемый пост)
У вас обоих не учтено самоприсваивание. 

Вечно я про это забываю... Спасибо за замечание smile.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0833 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.