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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Pattern copy on write 
:(
    Опции темы
sol78
Дата 15.12.2007, 15:14 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



pitayusь realizovatь pattern "Copy on Write"
Код

my_string::my_string(const char* str):c_str(0), length(0), count_ptr(0)
{
    if(str)
    {
        length=strlen(str)+1;
        c_str=new char[length];
        strcpy(c_str, str);
    }
    cout << "Constructor" <<'\n';
}


my_string::my_string(my_string& str): length(str.length), c_str(0), count_ptr(++str.count_ptr)
{
    c_str=str.c_str;
    cout << count_ptr ;
    cout << "CopyConstructor" <<'\n';
}


void my_string::display()const

    cout << "------------------" << '\n';
    cout << c_str << '\n';
    cout << count_ptr << '\n';
    cout << "------------------" << '\n';
}


int my_string::replace(char old_ch , char new_ch)
{
    int index=0;
    int count_ch=0;
    char* tmp_str=c_str;

    
    c_str=new char[length];
    
    if(c_str)
    {
        strcpy(c_str, tmp_str);
        while(c_str[index] != '\0')
        {
            if(c_str[index]==old_ch)
            {
               c_str[index]=new_ch;
               count_ch++;
            }
            index++;
        }
    }
    return count_ch;
}


my_string::~my_string()
{
    if(count_ptr==0)
    {
        cout << "delete" << '\n';
        delete [] c_str;
        
    }
    else  count_ptr--;
    cout << "Destructor" << '\n';
}

Код

#ifndef _MY_STRING
#define _MY_STRING
#include <string>
#include <iostream>
using std::cout;

class my_string
{
    char* c_str;
    size_t length;
    int count_ptr;
    public:
        my_string(const char* str=0); //Constructor
        my_string(my_string&);        //CopyConstructor
        void display()const;
        int replace(char , char);
        ~my_string();                 //Destructor
};

#endif

no ne poluchaetsya ,  v func  replace(char old_ch , char new_ch), poidee nuzhno count_ptr sbrasivat' na 0, ne znayu kak pravil'no eto sdelat'???

P.S. zhal' chto Translit ne rabotaet
PM MAIL   Вверх
zkv
Дата 15.12.2007, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

Репутация: 26
Всего: 92



Цитата(sol78 @  15.12.2007,  15:14 Найти цитируемый пост)
no ne poluchaetsya ,  v func  replace(char old_ch , char new_ch), poidee nuzhno count_ptr sbrasivat' na 0, ne znayu kak pravil'no eto sdelat'???

недостаточно просто сбросить счетчик в новом объекте, нужно еще уменьшить его во всех других строках, использующих этот участок памяти.
с учетом этого, думаю лучше держать в объектах указатель на счетчик:
Код

    size_t *length;

при выделении памяти на объект выделять память под счетчик, и устанавливать его в 0.
при копировании инкрементировать его, при модификации объекта сначала проверять есть ли ссылающиеся объекты, если нет - то просто модифицировать, если есть, то сначала декрементировать текущий счетчик, затем выделить память под новый, установить в ноль, скопировать буфер, теперь можно модифицировать.

понятно изложил?
PM MAIL   Вверх
sol78
Дата 15.12.2007, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



aga ukazatel' na chetchik....ok poprobuyu...
PM MAIL   Вверх
bsa
Дата 15.12.2007, 16:36 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 63
Всего: 196



имхо, лучше делать это так:
Код
class String
{
       struct Descriptor {
             char *begin, *end;
             unsigned count;
             Descriptor() : begin(0), end(0), count(0){}
             ~Descriptor() { delete begin; }
       };
       Descriptor *data;
public:
       String(void) : data(0) {}
       String(const char *str) {
             data = new Descriptor;
             assign(str);
       }
       ~String() {
             clear();
       }
       String(const String &value) : data(value.data) {
           if (data)
               ++data->count;
       }
       void clear(void) {
           if (data && data->count)
                --data->count;
           else
                delete data;
           data = 0;
       }
       void assign(const char *str) {
           clear();
           const std::size_t size = std::strlen(str);
           if (size) {
               data = new Descriptor;
               data->begin = new char[size+1];
               std::strcpy(data->begin, str);
               data->end = str + size;
           }
       }
       void assign(const String &str) {
           clear();
           data = str.data;
           if (data)
               ++data->count;
       }
       void swap(String &str) {
            Descriptor *t = data;
            data = str.data;
            str.data = t;
       }
       const char* c_str(void) const {
            return (data && data->begin) ? data->begin : "";
       }
       std::size_t size(void) const {
            return data ? (data->end - data->begin) : 0;
       }
       ....
};
Такая организация уменьшает количество указателей в самом классе. В итоге, в стеке выделяется место только под один указатель для каждого экземпляра String. А если строка не пустая, то выделяется память еще под два указателя (begin и end) и счетчик ссылок.
PM   Вверх
JackYF
Дата 15.12.2007, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(sol78 @  15.12.2007,  16:26 Найти цитируемый пост)
aga ukazatel' na chetchik....ok poprobuyu... 

если нет возможности писать в русской раскладке, то пользуйся галочкой "транслит" слева


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


Гентозавр
****


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

Репутация: 19
Всего: 181



 smile 
Цитата(JackYF @  15.12.2007,  14:45 Найти цитируемый пост)
если нет возможности писать в русской раскладке, то пользуйся галочкой "транслит" слева 

Она к сожалению в данный момент не работает, но это скоро пофиксят.


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
baldina
Дата 15.12.2007, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



bsa,

Цитата

имхо, лучше делать это так


+1

Цитата

Такая организация уменьшает количество указателей в самом классе


Еще чуть и заодно получим pattern pimpl
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0786 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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