Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 5.00
Alex_oo7
50 / 61 / 4
Регистрация: 18.10.2010
Сообщений: 240
#1

copy on write оптимизация - C++

15.05.2012, 02:24. Просмотров 1580. Ответов 20
Метки нет (Все метки)

Требуется сделать copy on write оптимизацию, но я не знаю как мне верно перенаправлять указатели / ссылки
Оптимизация состоит в том, что бы полностью копировать объект только при новой записи.

Как такое можно провернуть ?
Я примерно представил, что нужно грамотно определить оператор =
C++
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
bool replace;
std::vector<int> v, dv;
myclass() {     
        replace = false; 
        dv.resize(1);
        dv[0] = 0;
        std::vector<int>* p = &v;
        p = &dv;
    }
myclass(long get_i) {       
        replace = false; 
        dv.resize(1);
        dv[0] = get_i;
        std::vector<int>* p = &v;
        p = &dv;
    }
void operator =(myclass& a) {       
        if (a.replace) {
            dv = a.dv;
            std::vector<int>* p = &v;
            p = &dv;        
        } else {
            dv = a.dv;
            std::vector<int>* p = &v;
            p = &a.dv;              
        }
    }
Суть в том, что везде, кроме стандартного объявления myclass поле replace всегда true например при сложении вычитании и т.д.
Я создал собственное значение dv, и переменная v либо указывает на своё dv, либо на присвоенное a.dv

К переменной v всюду обращаются как к std::vector<int>

Но код что то не работает
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.05.2012, 02:24     copy on write оптимизация
Посмотрите здесь:

алгоритм copy C++
C++ copy в Delphi, аналог на C++?
this и Copy-Constructor C++
std::copy C++
C++ Deep copy and Shadow copy
C++ Вывод с copy
C++ STL. Алгоритм copy()
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
15.05.2012, 02:49     copy on write оптимизация #2
Цитата Сообщение от Alex_oo7 Посмотреть сообщение
C++
1
2
std::vector<int>* p = &v;
* * * * p = &dv
;
и толку от локальных указателей?
Alex_oo7
50 / 61 / 4
Регистрация: 18.10.2010
Сообщений: 240
15.05.2012, 11:14  [ТС]     copy on write оптимизация #3
Jupiter, не знаю

А как-нибудь можно сказать, что бы this целиком указывал на a ?
Что бы как в java объекты копировались...
То есть, если a=b, то у a только ссылка копируется из b
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
15.05.2012, 19:25     copy on write оптимизация #4
как-то так
C++
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
#include <iterator>
#include <memory>
#include <vector>
 
template< class T >
class copy_on_write_sample {
public:
    copy_on_write_sample() 
    : m_ptr(new std::vector<T>())
    , m_replace(false)
    , m_id(++m_counter)
    {
    }
 
    copy_on_write_sample(copy_on_write_sample const& c) 
    : m_ptr(c.m_ptr)
    , m_replace(true)
    , m_id(++m_counter)
    {
    }
 
    ~copy_on_write_sample()
    {
        std::cout << "copy_on_write_sample destr called for object #" << m_id <<"\n";
    }
 
    copy_on_write_sample& operator = (copy_on_write_sample const& c)
    {
        if (&c != this)
        {
            m_replace = true;
            m_ptr     = c.m_ptr;
        }
        return *this;
    }
 
    void push_back(T const& val)
    {
        if (m_replace)
        {
            auto new_ptr = std::shared_ptr<std::vector<T>>(new std::vector<T>());
            std::copy(m_ptr->begin(), m_ptr->end(), std::back_inserter(*new_ptr));
            m_ptr = new_ptr;
            m_replace = false;
        }
                
        m_ptr->push_back(val);
    }
private:
    std::shared_ptr<std::vector<T>> m_ptr;
    bool m_replace;
    int m_id;
    static int m_counter;
};
 
template< class T >
int copy_on_write_sample<T>::m_counter = 0;
 
struct test {
    test() { std::cout << "ctor called\n"; }
    test(test const&) { std::cout << "copy ctor\n"; }
    ~test() { std::cout << "desctor called\n"; }
};
 
int main()
{
    std::cout << "before copying:\n";
    copy_on_write_sample<test> t;
 
    {
        test a, b;
        t.push_back(a);
        t.push_back(b);
    }
 
    std::cout << "after copying:\n";
    copy_on_write_sample<test> p = t, k;
//    p.push_back(test());
    std::cout << "after assigment:\n";
    k = p;
}
Alex_oo7
50 / 61 / 4
Регистрация: 18.10.2010
Сообщений: 240
15.05.2012, 20:40  [ТС]     copy on write оптимизация #5
Jupiter, мда, как то это всё очень сложно

Как всё таки сделать, что бы переменная A указывала на то, на что указывает B ?
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
15.05.2012, 20:46     copy on write оптимизация #6
Alex_oo7, почитайте о смарт-указателях, я использовал стандартный std::shared_ptr, но его можно легко реализовать самому и он значительно облегчит вам реализацию вашего задания

Добавлено через 2 минуты
Цитата Сообщение от Alex_oo7 Посмотреть сообщение
мда, как то это всё очень сложно
там всего 80 строк включая тестовый пример, задавайте конкретные вопросы - что непонятно?
m_counter - подсчёт к-тва объектов я ввел лишь для того чтоб показать что данные действительно копируются/не копируются в зависимости от работы с контейнером
Avazart
7044 / 5221 / 259
Регистрация: 10.12.2010
Сообщений: 22,949
Записей в блоге: 17
15.05.2012, 20:57     copy on write оптимизация #7
Оптимизация состоит в том, что бы полностью копировать объект только при новой записи.
А в остальных случаях что делать?
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
15.05.2012, 21:00     copy on write оптимизация #8
Цитата Сообщение от Avazart Посмотреть сообщение
А в остальных случаях что делать?
использовать данные изначального объекта
Alex_oo7
50 / 61 / 4
Регистрация: 18.10.2010
Сообщений: 240
15.05.2012, 21:21  [ТС]     copy on write оптимизация #9
Как всё таки сказать a, что бы она указывала на то же самое, что и b ?
Или же объявить указатель std::vector<int>* p = &a.dv
И вместо a.v обращаться к *a.p, я прав ?
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
15.05.2012, 21:37     copy on write оптимизация #10
C++
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
#include <iostream>
#include <vector>
 
template< class T >
class copy_on_write_sample {
public:
    copy_on_write_sample() 
    : m_vec()
    , m_pvec(&m_vec)
    , m_replace(false)
    {}
 
    copy_on_write_sample(copy_on_write_sample const& t) 
    : m_vec()
    , m_pvec(t.m_pvec)
    , m_replace(true)
    {}
 
    copy_on_write_sample& operator = (copy_on_write_sample const& t)
    {
        m_replace = true;
        m_pvec    = t.m_pvec;
        return *this;
    }
 
    void push_back(T const& val)
    {
        if (m_replace)
        {
            m_replace = false;
            m_vec = *m_pvec;
            m_pvec = &m_vec;
        }
 
        m_pvec->push_back(val);
    }
private:
    std::vector<T>  m_vec;
    std::vector<T>* m_pvec;
    bool m_replace;
};
Alex_oo7
50 / 61 / 4
Регистрация: 18.10.2010
Сообщений: 240
20.05.2012, 19:58  [ТС]     copy on write оптимизация #11
Jupiter, что то я недопонял
Почему оператор = не void ?

Как быть, если я меняю данные ?
Например:
C++
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
class myclass {
public:
 
    string str;
    bool replace;
    
    myclass(){
        str = ""
        replace = false;    
    }
    
    myclass(int i){
        str = int2string(i);
        replace = false;
    }
 
    myclass(string s){
        str = s;
        replace = false;
    }       
}
 
myclass operator +(meclass& a, myclass& b){
    myclass c;
    c.replace = true;   
    c.str = a.str + b.str;
}
Какой тогда должен быть оператор = ?
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
20.05.2012, 20:07     copy on write оптимизация #12
Цитата Сообщение от Alex_oo7 Посмотреть сообщение
Почему оператор = не void ?
для того чтоб можно было делать так: a = b = c = d = e;
Alex_oo7
50 / 61 / 4
Регистрация: 18.10.2010
Сообщений: 240
20.05.2012, 20:28  [ТС]     copy on write оптимизация #13
Jupiter, а как быть с оператором "равно" ?
C++
1
2
3
4
5
6
7
8
9
10
11
myclass& operator =(myclass& a){
    if (a.replace) {
        myclass b;
        *this = &b;
        replace = false;
        str = a.str;
    } else {
        *this = a;
    }
    return *this;
}
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
20.05.2012, 20:30     copy on write оптимизация #14
Alex_oo7, оператор равно не изменяет данные, он должен скопировать указатели и установить флаг replace = true
Alex_oo7
50 / 61 / 4
Регистрация: 18.10.2010
Сообщений: 240
20.05.2012, 21:07  [ТС]     copy on write оптимизация #15
Jupiter, я хочу немного по другому реализовать, но для этого мне нужно знать, как у объекта сменить указатель ???
Alex_oo7
50 / 61 / 4
Регистрация: 18.10.2010
Сообщений: 240
23.05.2012, 03:33  [ТС]     copy on write оптимизация #16
Возникла новая проблема
Если я напишу

myclass q = myclass("test");
то у q указатель на строку будет указывать на нечто пустое

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class myclass {
    string str;
    string* link;
    bool copy;
    myclass(string s){
        copy = false;
        str = s;
        link = &str;
    }
    myclass& operator =(myclass& a) {
        copy = true;
        link = &a.str;
        return *this;
    }
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
23.05.2012, 12:01     copy on write оптимизация #17
Цитата Сообщение от Alex_oo7 Посмотреть сообщение
то у q указатель на строку будет указывать на нечто пустое
потому что нет конструктора копии
Alex_oo7
50 / 61 / 4
Регистрация: 18.10.2010
Сообщений: 240
23.05.2012, 19:32  [ТС]     copy on write оптимизация #18
Jupiter, добавил

C++
1
2
3
4
myclass(myclass& a) {
        copy = true;
        link = &a.str;       
    }
Всё равно не работает, как будто, что то уничтожает myclass("test"), после присвоения.
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
23.05.2012, 19:42     copy on write оптимизация #19
Цитата Сообщение от Alex_oo7 Посмотреть сообщение
myclass q = myclass("test");
Цитата Сообщение от Alex_oo7 Посмотреть сообщение
Всё равно не работает, как будто, что то уничтожает myclass("test"), после присвоения
правильно, так и есть myclass("test") временный объект
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.05.2012, 19:44     copy on write оптимизация
Еще ссылки по теме:

C++ copy, iterator, vector
Перегрузка copy() C++
C++ Copy constructor
C++ Алгоритм copy
Пример функции для изменения региона защиты памяти процесса с Read Only на Write Copy C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Alex_oo7
50 / 61 / 4
Регистрация: 18.10.2010
Сообщений: 240
23.05.2012, 19:44  [ТС]     copy on write оптимизация #20
Jupiter, а как тогда быть ?
Как определить, что объект временный ?
Yandex
Объявления
23.05.2012, 19:44     copy on write оптимизация
Ответ Создать тему
Опции темы

Текущее время: 13:32. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru