Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.80/10: Рейтинг темы: голосов - 10, средняя оценка - 4.80
Alex_oo7
50 / 61 / 16
Регистрация: 18.10.2010
Сообщений: 240
#1

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

15.05.2012, 02:24. Просмотров 1869. Ответов 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>

Но код что то не работает
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.05.2012, 02:24
Ответы с готовыми решениями:

Пример функции для изменения региона защиты памяти процесса с Read Only на Write Copy
будьте добры привести пример функции для изменения региона защиты памяти...

Deep copy and Shadow copy
Этот проект компилируется нормально. И функциональность всех элементов на...

Алгоритм copy
У меня есть вектор указателей vector&lt;cString *&gt; (cString - это мой класс),...

Функция copy
Задача: скопировать файл .exe допустим из C:\Documents and...

Перегрузка copy()
Здравствуйте, уважаемые. Пробую создать копию библиотечной функции copy(): ...

20
Jupiter
Каратель
Эксперт С++
6569 / 3990 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
15.05.2012, 02:49 #2
Цитата Сообщение от Alex_oo7 Посмотреть сообщение
C++
1
2
std::vector<int>* p = &v;
* * * * p = &dv
;
и толку от локальных указателей?
0
Alex_oo7
50 / 61 / 16
Регистрация: 18.10.2010
Сообщений: 240
15.05.2012, 11:14  [ТС] #3
Jupiter, не знаю

А как-нибудь можно сказать, что бы this целиком указывал на a ?
Что бы как в java объекты копировались...
То есть, если a=b, то у a только ссылка копируется из b
0
Jupiter
Каратель
Эксперт С++
6569 / 3990 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
15.05.2012, 19:25 #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;
}
0
Alex_oo7
50 / 61 / 16
Регистрация: 18.10.2010
Сообщений: 240
15.05.2012, 20:40  [ТС] #5
Jupiter, мда, как то это всё очень сложно

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

Добавлено через 2 минуты
Цитата Сообщение от Alex_oo7 Посмотреть сообщение
мда, как то это всё очень сложно
там всего 80 строк включая тестовый пример, задавайте конкретные вопросы - что непонятно?
m_counter - подсчёт к-тва объектов я ввел лишь для того чтоб показать что данные действительно копируются/не копируются в зависимости от работы с контейнером
0
Avazart
Эксперт С++
7717 / 5626 / 549
Регистрация: 10.12.2010
Сообщений: 25,322
Записей в блоге: 17
15.05.2012, 20:57 #7
Оптимизация состоит в том, что бы полностью копировать объект только при новой записи.
А в остальных случаях что делать?
0
Jupiter
Каратель
Эксперт С++
6569 / 3990 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
15.05.2012, 21:00 #8
Цитата Сообщение от Avazart Посмотреть сообщение
А в остальных случаях что делать?
использовать данные изначального объекта
0
Alex_oo7
50 / 61 / 16
Регистрация: 18.10.2010
Сообщений: 240
15.05.2012, 21:21  [ТС] #9
Как всё таки сказать a, что бы она указывала на то же самое, что и b ?
Или же объявить указатель std::vector<int>* p = &a.dv
И вместо a.v обращаться к *a.p, я прав ?
0
Jupiter
Каратель
Эксперт С++
6569 / 3990 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
15.05.2012, 21:37 #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;
};
2
Alex_oo7
50 / 61 / 16
Регистрация: 18.10.2010
Сообщений: 240
20.05.2012, 19:58  [ТС] #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;
}
Какой тогда должен быть оператор = ?
0
Jupiter
Каратель
Эксперт С++
6569 / 3990 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
20.05.2012, 20:07 #12
Цитата Сообщение от Alex_oo7 Посмотреть сообщение
Почему оператор = не void ?
для того чтоб можно было делать так: a = b = c = d = e;
0
Alex_oo7
50 / 61 / 16
Регистрация: 18.10.2010
Сообщений: 240
20.05.2012, 20:28  [ТС] #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;
}
0
Jupiter
Каратель
Эксперт С++
6569 / 3990 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
20.05.2012, 20:30 #14
Alex_oo7, оператор равно не изменяет данные, он должен скопировать указатели и установить флаг replace = true
0
Alex_oo7
50 / 61 / 16
Регистрация: 18.10.2010
Сообщений: 240
20.05.2012, 21:07  [ТС] #15
Jupiter, я хочу немного по другому реализовать, но для этого мне нужно знать, как у объекта сменить указатель ???
0
Alex_oo7
50 / 61 / 16
Регистрация: 18.10.2010
Сообщений: 240
23.05.2012, 03:33  [ТС] #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;
    }
0
Jupiter
Каратель
Эксперт С++
6569 / 3990 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
23.05.2012, 12:01 #17
Цитата Сообщение от Alex_oo7 Посмотреть сообщение
то у q указатель на строку будет указывать на нечто пустое
потому что нет конструктора копии
1
Alex_oo7
50 / 61 / 16
Регистрация: 18.10.2010
Сообщений: 240
23.05.2012, 19:32  [ТС] #18
Jupiter, добавил

C++
1
2
3
4
myclass(myclass& a) {
        copy = true;
        link = &a.str;       
    }
Всё равно не работает, как будто, что то уничтожает myclass("test"), после присвоения.
0
Jupiter
Каратель
Эксперт С++
6569 / 3990 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
23.05.2012, 19:42 #19
Цитата Сообщение от Alex_oo7 Посмотреть сообщение
myclass q = myclass("test");
Цитата Сообщение от Alex_oo7 Посмотреть сообщение
Всё равно не работает, как будто, что то уничтожает myclass("test"), после присвоения
правильно, так и есть myclass("test") временный объект
0
Alex_oo7
50 / 61 / 16
Регистрация: 18.10.2010
Сообщений: 240
23.05.2012, 19:44  [ТС] #20
Jupiter, а как тогда быть ?
Как определить, что объект временный ?
0
23.05.2012, 19:44
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.05.2012, 19:44

this и Copy-Constructor
Скажите пожалуйста почему даный еод вызывает RTE(Run Time Error) Добавлено...

Вывод с copy
Не могли бы вы показать/рассказать про вывод, например, массива, с...

Copy constructor
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; using namespace::std; class alpha{...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru