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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Smart Pointer 
:(
    Опции темы
sol78
Дата 27.1.2008, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 0



как правильно написать свой Smart Pointer (не универсальный) а скажем,  для своего класса String??
- что иммено в нем должно бить?
вот я тут набрасала:
.h
Код

#ifndef _SMART_PTR
#define _SMART_PTR
#include <string>

class SmartPtr
{
    char* buff;
    SmartPtr * next;
    SmartPtr * prev;
    static SmartPtr* head;
    int count;
    SmartPtr(const char* buff=0);// constructor
    ~SmartPtr(); //Destructor
    SmartPtr* getSPbyValue(const char* buff);
public:
    static SmartPtr* createMemory(const char*);
    static bool destroyMemory(SmartPtr*);
    const char* get_buff();
    bool update(const char* );
};


#endif


.cpp
Код

#include "SmartPtr.h"

SmartPtr::SmartPtr(const char* str):count(0), buff(0), next(0), prev(0)
{
    if(str){
        ++count; //count ==1, is original
        buff=new char[strlen(str)+1];
        strcpy(buff, str);
    }
}

SmartPtr* SmartPtr::head=0;

SmartPtr::~SmartPtr()
{
    delete[] buff;
}


SmartPtr* SmartPtr::createMemory(const char* str)
{
        SmartPtr* ptr;
        
        if(head==0)
        {
            ptr=new SmartPtr(str);
            head=ptr;
            head->prev=0;
        }
    
        else
        {
            ptr=SmartPtr::head;
            if(ptr->getSPbyValue(str)!=0)
            { //str exists
                ptr->count++;
            }
            else
            { //str not exists
               ptr=new SmartPtr(str);
               head->prev=ptr;
               ptr->next=head;
               head=ptr;
            }
        }
   return ptr;
}

SmartPtr* SmartPtr::getSPbyValue(const char* buff)
{
    SmartPtr* tmp;
    
    if(SmartPtr::head)
    {
        tmp=SmartPtr::head;
        while(tmp)
        {
            if(strcmp(tmp->buff, buff)==0)
            {
               return tmp;
            }
            tmp=tmp->next;
        }
    }
    return 0;
}




 bool SmartPtr::destroyMemory(SmartPtr* ptr)
 {
     bool rc=false;

     if(ptr)
     {
         if(ptr->count==1)// is original
         {
             if(head->next==0)//ptr is single
             {
                 head=0;
             }

             else if(ptr==head)//ptr in head
             {
                 head=ptr->next;
                 head->prev=0;
             }
             else if (ptr->next==0)//ptr in tail (last)
             {
                 ptr->prev->next=0;
             }
             else //ptr is between 
             {
                 ptr->prev->next=ptr->next;
                 ptr->next->prev=ptr->prev;
             }
             delete ptr;
             rc=true;
         }
         else
             --(ptr->count);
     }
     return rc;
 }
//не работает........

 bool SmartPtr::update(const char* up_str)
 {
     bool rc=false;
     SmartPtr* tmp;

     if(strcmp(this->buff,up_str)!=0)
     {
               //destroy this
         SmartPtr::destroyMemory(this);

         if((tmp=getSPbyValue(up_str))!=0)
             //up_str exists
         {
;
             //this=tmp;
             tmp->count++;
         }
         else
         {
             SmartPtr::createMemory(up_str);
         }
         rc=true;
     }
     return rc;
 }             

        


 const char* SmartPtr::get_buff()
 {
     return this->buff;
 }




    

-т.ж. функция update(..) не работает, д/б реализован pattern copy on write (я так думаю..)
-С удовольствием приму все замечания и предложения!!!



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


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


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

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



Огласи-ка сначала задачи, которые этот смарт-поинтер должен выполнять. Я лично вот не понял.


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


Опытный
**


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

Репутация: 1
Всего: 0



1 считает ссылки
2 не дублирует обьекты, т.е. если есть стринг "вася" , другого быть не должно, просто увеличеваем счетчик..
3 реализует COW
4 удаление - гарбич коллектор

остальное и является вопросом...т.е. как его рассширить, чтобы класс Стринг стал  оочень простим?

Это сообщение отредактировал(а) sol78 - 27.1.2008, 22:32
PM MAIL   Вверх
Fazil6
Дата 27.1.2008, 22:38 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Код

#ifndef _SMART_PTR
#define _SMART_PTR
#include <string>        // на кой этот иклуд тут воткнут?

Цитата(sol78 @  27.1.2008,  21:01 Найти цитируемый пост)
т.ж. функция update(..) не работает, д/б реализован pattern copy on write (я так думаю..)

у меня закралось сильное сомнение, что мы по разному понимаем термин "smart pointer". Впервую очередь предполагается, что смартпоинтер используется по значению и имеет перегруженный конструктор копии и оператор присваивания. У тебя же какая-то замороченная обертка над массивом символов скорее смахивающая на попытку реализации строкового класса и честно говоря в логику его я не втыркнул особо.

Добавлено через 5 минут и 8 секунд
чем больше смотрю на эту реализацию, тем менее понимаю идеи. Вижу интерфейс
Код

public:
    static SmartPtr* createMemory(const char*);
    static bool destroyMemory(SmartPtr*);
    const char* get_buff();
    bool update(const char* );

слабо себе представляю зачем такие функции у смартпоинтера и как я бы им пользовался. 
PM MAIL   Вверх
JackYF
Дата 27.1.2008, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Fazil6, вот у меня такие же мысли.

sol78, давай пример использования этой штуки в студию.


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(Fazil6 @  27.1.2008,  22:38 Найти цитируемый пост)
слабо себе представляю зачем такие функции у смартпоинтера и как я бы им пользовался. 

А я слабо себе представляю как можно пользоваться смарт поинтером не реализующим операторы -> и *  smile 
смарт поинтер должен иметь ту-же семантику что и указатель

Добавлено через 1 минуту и 45 секунд
Джеф Элджер - "Библиотека программиса" - почти вся книга про смарт поинтеры
PM MAIL Skype GTalk   Вверх
JackYF
Дата 28.1.2008, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Lazin @  27.1.2008,  23:10 Найти цитируемый пост)
почти вся книга про смарт поинтеры 

может, всё-таки одна треть? smile там ещё немало полезного по другим темам.


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


Опытный
**


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

Репутация: 1
Всего: 0



Цитата(Fazil6 @ 27.1.2008,  22:38)

у меня закралось сильное сомнение, что мы по разному понимаем термин "smart pointer". Впервую очередь предполагается, что смартпоинтер используется по значению и имеет перегруженный конструктор копии и оператор присваивания. У тебя же какая-то замороченная обертка над массивом символов скорее смахивающая на попытку реализации строкового класса и честно говоря в логику его я не втыркнул особо.

Я согласна, что интерфейс не годиться....
поэтому возник данный вопрос. - как правильно написать свой Smart Pointer (не универсальный) а скажем,  для своего класса String??

О примере использования могу только сказать что
Код

SmartPtr* ptr= new SmartPtr();//ошибка компиляции

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


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


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

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



Цитата(sol78 @  28.1.2008,  13:20 Найти цитируемый пост)
как правильно написать свой Smart Pointer (не универсальный) а скажем,  для своего класса String

Тут уже советовали - почитай, к примеру, Джеффа Элджера, у него эта тема много и с разных сторон мусолится.


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Идиома COW хорошо описана в книге - С. Мейерс "Наиболее эффективное использование С++". Там в конце книги есть примеры программирования, один из них, это как раз реализация COW на примере строк.
PM MAIL Skype GTalk   Вверх
Ulysses4j
Дата 28.1.2008, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 6.6.2007
Где: Ростов-на-Дону

Репутация: 4
Всего: 10



Цитата(sol78 @ 28.1.2008,  15:20)
О примере использования могу только сказать что
Код

SmartPtr* ptr= new SmartPtr();//ошибка компиляции

Умные укзатели это классы, объекты которых обычно используются по значению, так что вам нужно ориентироваться на интерфейс вроде
Код
SmartPt ptr(/*???*/);

Конструктора по умолчанию быть не должно: другая отличительная черта умных указателей это использование идиомы RAII - Resource Acquisition Is Initialization (захват ресурса на стадии инициализации). Поясню. Умные указатели предназначены для автоматизации управления ресурсами, которые требуют ручной инициализации и зачистки, примером в вашем случае может служить символьная строка в динамической памяти (куче) — память нужно выделять new, а зачищать - delete. RAII означает, что захват управляемых ресурсов должен происходить при инициализации объекта класса умного указателя, то есть примерно так:
Код
SmartPt ptr( new char[n] );

Клиентскому коду, использующему ваш умный укзатель, достаточно вызвать только конструктор, как показано выше, delete же будет вызван в деструкторе SmartPt, незаметно для клиента.
Код

class SmartPointer {
  char* data;
  // ...
public:
  SmartPointer(char* aData) : data(aData) {}
// ...
  ~SmartPointer() { delete[] data; }
}

Далее необходимо реализовать в вашем классе хотя бы минимальный традиционный интерфейс указателей, как был совершенно справедливо указано выше - operator*() и operator++().

Важным моментом является реализация операций копирования (конструктора копирования и операции копирующего присваивания — SmartPointer(SmartPointer const&) и operator=(SmartPointer const&)). Для начала я советую реализовать самый простой вариант, когда при копировании умных указателей, копируются соответсвующие сегменты памяти. За copy-on-write и подсчет ссылок лучше взяться потом.

Это сообщение отредактировал(а) Ulysses4j - 28.1.2008, 15:11


--------------------
Communication is critical to the job of a programmer.
C. Jazdzewski. Fatherly Advice To New Programmers
PM MAIL WWW   Вверх
Fazil6
Дата 28.1.2008, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата(Ulysses4j @  28.1.2008,  14:08 Найти цитируемый пост)
Конструктора по умолчанию быть не должно

почему же? Вполне может быть конструктор поумолчанию
PM MAIL   Вверх
Ulysses4j
Дата 28.1.2008, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 6.6.2007
Где: Ростов-на-Дону

Репутация: 4
Всего: 10



Да, погорячился, идиоматический вызов с new сбил с толку.

Это сообщение отредактировал(а) Ulysses4j - 28.1.2008, 15:54


--------------------
Communication is critical to the job of a programmer.
C. Jazdzewski. Fatherly Advice To New Programmers
PM MAIL WWW   Вверх
sol78
Дата 28.1.2008, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 0



Спасибо за советы!
Вопрос конкретный :
как мне написать конструктор для SmartPointer, который не дублирует обьекты, т.е. если есть  уже "вася"
нового "вася" быть не должно . И результат его работы : this указывает на существующий  smart pointer
и  counter++;?

Добавлено через 1 минуту и 21 секунду
Цитата(Fazil6 @  28.1.2008,  15:32 Найти цитируемый пост)
почему же? Вполне может быть конструктор поумолчанию 

да тут без вопросов
PM MAIL   Вверх
Fazil6
Дата 28.1.2008, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата(sol78 @  28.1.2008,  14:53 Найти цитируемый пост)
как мне написать конструктор для SmartPointer, который не дублирует обьекты, т.е. если есть  уже "вася"

сделать ставический список, где лежат все значения. При создании нового экземпляра смотреть в этом списке. Тока нужна синхронизация для многопоточности и это не COW.
PM MAIL   Вверх
Lazin
Дата 28.1.2008, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Вот такой вот велосипед я однажды написал...

Код

    /*!
     * Счётчик ссылок
     * Класс предназначен для открытого наследования, 
     * класс потомок должен иметь защищённый конструктор и
     * защищённый деструктор.
     */
    class FRAMEWORK_ENTRY reference_counter
    {
        template <class T>
        friend class reference;

        private:
            /*!счётчик объектов*/
            static unsigned long count;
            /*!счетчик ссылок на объект*/
            unsigned long ReferenceCounter;
        protected:
            //!Конструктор по умолчанию
            reference_counter(): ReferenceCounter(0) {++count;}
            //!Конструктор копий (ничего не делает)
            reference_counter(const reference_counter&) {}
            //!Оператор присваивания (ничего не делает)
            reference_counter& operator = (const reference_counter&) {return *this;}
        
            //!Деструктор
            virtual ~reference_counter() {--count;}
        private:
            //!Захватить объект
            void grab() throw() { ++ReferenceCounter; }
            //!Освободить объект
            bool drop()
            {    if (ReferenceCounter) --ReferenceCounter;
                if (ReferenceCounter == 0) 
                {    delete this;
                    return true;
                }
                return false;
            }
        public:
            //!Получить колличество объектов
            static unsigned long get_created_count() {return count;}
    };

    /*!
     *    Сильный указатель с подсчётом ссылок и семантикой значений
     */
    template <class Class>
    class reference
    {
    protected:
        Class* pointee;
        typedef Class* type_trait;
    public:
        reference() :pointee(0) {}

        reference(Class *p) :pointee(p)
        {    if (pointee) pointee->grab();
        }

        reference(const reference<Class> &ref) :pointee(ref.pointee)
        {    if (pointee) pointee->grab();
        }

        reference<Class>& operator = (const reference<Class>& ref)
        {    if (this == &ref) return *this;
            if (pointee) pointee->drop();
            pointee = ref.pointee;
            if (pointee) pointee->grab();
            return *this;
        }

        ~reference()
        {    if (pointee) pointee->drop();
        }

        Class* operator->() {return pointee;}

        const Class* operator->() const {return pointee;}

        Class& operator* () {return *pointee;}

        const Class& operator* () const {return *pointee;}

        bool operator == (const reference<Class>& rhs) const { return (pointee == rhs.pointee); }

        bool operator != (const reference<Class>& rhs) const { return (pointee != rhs.pointee); }

        bool operator == (const Class* rhs) const { return (pointee == (Class*)rhs); }

        bool operator != (const Class* rhs) const { return (pointee != (Class*)rhs); }

        //!Ф-я преобразует указатель к типу reference<CastType>
        template<typename CastType>
        reference<CastType> cast()
        {    return reference<CastType>((CastType*)pointee);
        }

        //!Ф-я преобразует указатель к типу reference<CastType>
        template<typename CastType>
        operator CastType() const
        {    return CastType(pointee);
        }
    };  

Цитата(sol78 @  28.1.2008,  15:53 Найти цитируемый пост)
Вопрос конкретный :
как мне написать конструктор для SmartPointer, который не дублирует обьекты, т.е. если есть  уже "вася"
нового "вася" быть не должно . И результат его работы : this указывает на существующий  smart pointer
и  counter++;?

отнаследовать от класса reference_counter, а затем работать через класс reference, прикол этого кода в том, что с потомками reference_counter никак иначе, кроме как через смарт поинтер работать нельзя...
PM MAIL Skype GTalk   Вверх
JackYF
Дата 28.1.2008, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Lazin, мне очень даже с виду понравилось. Какая лицензия у этого исходника? Под GPLv3 можно стырить? smile


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(JackYF @  28.1.2008,  16:38 Найти цитируемый пост)
Под GPLv3 можно стырить?
а это как?

PM MAIL Skype GTalk   Вверх
JackYF
Дата 28.1.2008, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Lazin @  28.1.2008,  16:11 Найти цитируемый пост)
а это как?

ээээ... ну если в трёх словах, ты объявляешься автором данного кода со всеми вытекающими + разрешаешь всему сообществу изменять код как заблагорассудится при условии сохранения твоих авторских прав smile
а так - на http://www.gnu.org/licenses/gpl-3.0.html всё расписано.


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Код

/*
    Smart pointer class
    Copyright (C) 2008  Lazin
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
    /*!
     * Счётчик ссылок
     * Класс предназначен для открытого наследования, 
     * класс потомок должен иметь защищённый конструктор и
     * защищённый деструктор.
     */
    class FRAMEWORK_ENTRY reference_counter
    {
        template <class T>
        friend class reference;
        private:
            /*!счётчик объектов*/
            static unsigned long count;
            /*!счетчик ссылок на объект*/
            unsigned long ReferenceCounter;
        protected:
            //!Конструктор по умолчанию
            reference_counter(): ReferenceCounter(0) {++count;}
            //!Конструктор копий (ничего не делает)
            reference_counter(const reference_counter&) {}
            //!Оператор присваивания (ничего не делает)
            reference_counter& operator = (const reference_counter&) {return *this;}
        
            //!Деструктор
            virtual ~reference_counter() {--count;}
        private:
            //!Захватить объект
            void grab() throw() { ++ReferenceCounter; }
            //!Освободить объект
            bool drop()
            {    if (ReferenceCounter) --ReferenceCounter;
                if (ReferenceCounter == 0) 
                {    delete this;
                    return true;
                }
                return false;
            }
        public:
            //!Получить колличество объектов
            static unsigned long get_created_count() {return count;}
    };
    /*!
     *    Сильный указатель с подсчётом ссылок и семантикой значений
     */
    template <class Class>
    class reference
    {
    protected:
        Class* pointee;
        typedef Class* type_trait;
    public:
        reference() :pointee(0) {}
        reference(Class *p) :pointee(p)
        {    if (pointee) pointee->grab();
        }
        reference(const reference<Class> &ref) :pointee(ref.pointee)
        {    if (pointee) pointee->grab();
        }
        reference<Class>& operator = (const reference<Class>& ref)
        {    if (this == &ref) return *this;
            if (pointee) pointee->drop();
            pointee = ref.pointee;
            if (pointee) pointee->grab();
            return *this;
        }
        ~reference()
        {    if (pointee) pointee->drop();
        }
        Class* operator->() {return pointee;}
        const Class* operator->() const {return pointee;}
        Class& operator* () {return *pointee;}
        const Class& operator* () const {return *pointee;}
        bool operator == (const reference<Class>& rhs) const { return (pointee == rhs.pointee); }
        bool operator != (const reference<Class>& rhs) const { return (pointee != rhs.pointee); }
        bool operator == (const Class* rhs) const { return (pointee == (Class*)rhs); }
        bool operator != (const Class* rhs) const { return (pointee != (Class*)rhs); }
        //!Ф-я преобразует указатель к типу reference<CastType>
        template<typename CastType>
        reference<CastType> cast()
        {    return reference<CastType>((CastType*)pointee);
        }
        //!Ф-я преобразует указатель к типу reference<CastType>
        template<typename CastType>
        operator CastType() const
        {    return CastType(pointee);
        }
    };  

 smile 
PM MAIL Skype GTalk   Вверх
JackYF
Дата 29.1.2008, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Lazin, смеёшься smile) Спасибо, теперь могу забрать к себе в копилку smile


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


Опытный
**


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

Репутация: 1
Всего: 0



Я просто в тупике
вот один конструктор для SP ни как не продвигается, гляньте плз,

Код

#ifndef _SMART_PTR
#define _SMART_PTR
#include <string>

class SmartPointer
{
    char* buff;
    SmartPointer * next;
    SmartPointer * prev;
    static SmartPointer* head;
    int count;
    SmartPointer* getSPbyValue(const char* buff);
    void addSmartPointer(const char* str);
    void SmartPointer::InitSmartPointer(const char* str);



public:
    SmartPointer(const char* buff=0);// constructor
    SmartPointer(const SmartPointer & sp);//CopyConstructor
    ~SmartPointer(); //Destructor
    
    const char* get_buff();
    bool update(const char* );
};


#endif


вырезаю все остальное еще не написано
Код

#include "SmartPointer.h"

SmartPointer::SmartPointer(const char* str):count(0), buff(0), next(0), prev(0)
{

    if(str){
        this->addSmartPointer(str);
    }
}
void SmartPointer::InitSmartPointer(const char* str)
{
    if(str)
    {
         ++count; //count ==1, is original
         buff=new char[strlen(str)+1];
         strcpy(buff, str);
    }
}





SmartPointer* SmartPointer::head=0;


void SmartPointer::addSmartPointer(const char* str)
{
        SmartPointer* ptr;
        
        if(head==0)
        {
            head=this;
            head->prev=0;
            InitSmartPointer(str);
        }
    
        else
        {
            if((ptr=getSPbyValue(str))!=0)
            { //str exists
                                      //this dolzhen ukazivat' na ptr??
            
                ptr->count++;
            }
            else
            { //str not exists
               head->prev=ptr;
               this->next=head;
               head=ptr;
               InitSmartPointer(str);
            }
        }
}

SmartPointer* SmartPointer::getSPbyValue(const char* buff)
{
    SmartPointer* tmp;
    
    if(SmartPointer::head)
    {
        tmp=SmartPointer::head;
        while(tmp)
        {
            if(strcmp(tmp->buff, buff)==0)
            {
               return tmp;
            }
            tmp=tmp->next;
        }
    }
    return 0;
}




        
             

        


 const char* SmartPointer::get_buff()
 {
     return this->buff;
 }




    




Lazin,  спасибо за класс, но использовать его не могу  токовы требования 
PM MAIL   Вверх
JackYF
Дата 29.1.2008, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(sol78 @  29.1.2008,  15:00 Найти цитируемый пост)
SmartPointer::

это в объявлении класса ставить не нужно

Цитата(sol78 @  29.1.2008,  15:00 Найти цитируемый пост)
вот один конструктор для SP ни как не продвигается, гляньте плз,

увы, телепаты не скажут нам, какой это конструктор и что он должен делать...

Это сообщение отредактировал(а) JackYF - 29.1.2008, 17:32


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


Опытный
**


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

Репутация: 1
Всего: 0



JackYF,  не множечко терпения

Код

//вызов конструктора
SmartPointer ptr("Vasya");
SmartPointer ptr1("Vasya");

в конструкторе:
-вызов ф. addSmartPointer(const char* str)
-там
Код

void SmartPointer::addSmartPointer(const char* str)
{
        SmartPointer* ptr;
        
        if(head==0)
        {
         //Первий сп как узел
            head=this;
            head->prev=0;
            InitSmartPointer(str);
        }
    
        else
        {
            if((ptr=getSPbyValue(str))!=0)// Существует ли точно такой стр
            { //str exists
                                     
            //Тут проблема нужно чтобы this указивал на тот же елемент???
                ptr->count++;
            }
            else
            { //str not exists
               //Строим новий узел и втыкаем его как новую голову
               head->prev=ptr;
               this->next=head;
               head=ptr;
               InitSmartPointer(str);
            }
        }
}


  
с помощью коменариев попробовала обьяаснить...
PM MAIL   Вверх
JackYF
Дата 29.1.2008, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(sol78 @  29.1.2008,  17:06 Найти цитируемый пост)
//Тут проблема нужно чтобы this указивал на тот же елемент???

this (как указатель) изнутри самого себя менять нельзя. Создавай новый объект, который уже указывает на нужную строку либо меняй архитектуру.


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


Опытный
**


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

Репутация: 1
Всего: 0



Проблема видемо в том что я не могу влиять (в необходимой мне степени) на обьект на уровне конструктора,
что остается вернутся с чаго начала?
Не ужели етот вариант тупиковый?
PM MAIL   Вверх
JackYF
Дата 29.1.2008, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(sol78 @  29.1.2008,  19:18 Найти цитируемый пост)
Не ужели етот вариант тупиковый? 

Пробуй другие варианты, которые приходят тебе в голову.
Возможно, это создание не одного централизованного списка, а все одинаковые строки хранят отдельные, "свои" списки.



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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



На мой взгляд COW - это как-то так:
Код

String s1 = "111";
String s2 = s1;//копирования не должно происходить
s2 = "222";//создается новая строка
String s3(s2);//копирования не должно происходить


Набросал небольшой пример, как можно это сделать... я использовал код который приводил выше
Здесь конечно все сильно упрощено, но идея должна быть понятна: объекты класса str_buffer содержат непосредственно данные(строки char-ов), объекты класса String - содержат ссылки на объекты str_buffer, при копировании строк, передаче по значению, копирования данных не происходит, копируются только ссылки (класс ссылки - reference) и при изменении количества ссылок на буфер, счетчик ссылок изменяется то-же, при обнулении счетчика ссылок буфер удаляется.
При изменении строки, просто выделяется новый буффер, а старый освобождается (его счетчик ссылок уменьшается на 1), если только одна строка использовала этот буфер он удалится.
Код

//класс - буфер для строки разделяемый между разными объектами
//используется только через "умный указатель"
class str_buffer : public reference_counter
{
char* buf;

  str_buffer(const char* str)
  {
    buf = new char[strlen(str)+1];
    strcpy(buf, str);// или наоборот strcpy(str, buf);)
  }

  ~str_buffer()
  {
    delete[] buf;
  }

public:

  char* get() {return buf;}

  void set(const char* str) {
    delete[] buf;
    buf = new char[strlen(str)+1];
    strcpy(buf, str);// или наоборот strcpy(str, buf);)
  }

   //производящая функция
   reference<str_buffer> make(const char* str) {return new str_buffer(str);}
};

typedef reference<str_buffer> str_buffer_ptr;

//класс - строка, содержит ссылку на буфер со строкой, при копировании просто получает ссылку на новый буффер
//при модификации строки, освобождает старый буфер и создает новый
class String
{
  str_buffer_ptr buffer; // <- буффер для хранения строки - то что должно разделяться между разными объектами String, 
  //по идее это умный указатель с подсчетом ссылок

  //constructor
  String(const char* str) : buffer( str_buffer::make(str) ) {}
  
  String (const String& str) {buffer = str.buffer;}

  String& operator = (const String& str) {buffer = str.bufer; return *this;}

  //read
  const char* c_str() {return buffer.get();}
  //модификация строки
  String& operator = (const char* str) 
  {
     buffer = str_buffer::make(str);//создается новый буфер под строку (даже если строка такая-же как и была)
     return *this;
  }
};

PM MAIL Skype GTalk   Вверх
sol78
Дата 31.1.2008, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 0



Lazin, 
до COW у меня еще руки не дошли...
но в принципе идея понятна...
Я заткнулась на счетчике ссылок и не дублиравание обьектов.... smile 
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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