С Новым годом! Форум программистов, компьютерный форум, киберфорум
Теория и практика программирования
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
1873 / 770 / 108
Регистрация: 01.10.2012
Сообщений: 4,180
1

Член указатель

09.07.2024, 23:01. Показов 1697. Ответов 52
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день

Очень простая конструкция
C++
1
2
3
4
5
struct SomeObject {
...
 SomeData * m_data;
...
};
Как минимум возникают заботы с сохранностью/валидностью m_data, но не только
Как лучше? Слышал такое

1) "Лучше иметь m_data членом, а не указателем". Это владение, а оно не всегда нужно/допустимо. В большинстве случаев SomeObject просто использует SomeData для чтения/записи, но SomeData остается вполне самостоятельным объектом что может существовать и без SomeObject

2) "Необходимо использовать вумный указатель! Вообще "голые" указатели (как в примере выше) - это зло, их быть вообще не должно!"

А Вы что предложите?

Спасибо
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.07.2024, 23:01
Ответы с готовыми решениями:

Функция-член принимает указатель на функцию-член
Задача состоит в следующем. Нужно реализовать функцию-член которая принимает указатель функцию-член...

Не могу создать указатель на функцию. ошибка: нестандартный синтаксис; используйте "&", чтобы создать указатель на член
Выбивает ошибку, когда хочу присвоить переменной адрес какой то функции. Ошибка в строке 28(если...

Указатель на функцию-член
// howmany.cpp: определяет точку входа для консольного приложения. // #include "stdafx.h"...

Указатель на фунцкию-член
class Letter { public: void(Letter::*side)(); Letter() { side = front; side =...

52
Модератор
Эксперт Java
2697 / 1196 / 386
Регистрация: 11.08.2017
Сообщений: 3,694
Записей в блоге: 2
09.07.2024, 23:37 2
Цитата Сообщение от Igor3D Посмотреть сообщение
Необходимо использовать вумный указатель
Они вроде как средство от ручного управления памятью, а проблем валидности не решают. В них тоже не может быть значения...
Хотя можно вместо указателя опционал, тогда можно избавиться от ручного управления памятью (объект будет на стэке по сути), но так же придется проверять валидность
0
фрилансер
5846 / 5376 / 1103
Регистрация: 11.10.2019
Сообщений: 14,367
10.07.2024, 09:01 3
Igor3D, мне кажется, в данном случае подойдёт std::shared_ptr
0
1873 / 770 / 108
Регистрация: 01.10.2012
Сообщений: 4,180
10.07.2024, 19:33  [ТС] 4
alecss131, Алексей1153, спасибо за ответы, но не могли бы Вы пояснить/показать подробнее? А то все намеками
0
фрилансер
5846 / 5376 / 1103
Регистрация: 11.10.2019
Сообщений: 14,367
10.07.2024, 19:59 5
Igor3D, а что именно будет происходить с этим указателем и с его обёрткой ?
0
1873 / 770 / 108
Регистрация: 01.10.2012
Сообщений: 4,180
11.07.2024, 14:08  [ТС] 6
Пример. Есть 100 SomeObject, возможно некоторые из них ссылаются на некоторые SomeData. Теперь нужно удалить один из SomeData. Ясно что указатель на него, хранимый SomeObject, становится невалидным. Придется найти всеx "клиентов" использующих удаляемый SomeData и обнулить в них указатели. Этот "поиск клиентов" выглядит трудоемко и коряво. Как его избежать? Напомню что на валидности указателя проблемы не кончаются
0
фрилансер
5846 / 5376 / 1103
Регистрация: 11.10.2019
Сообщений: 14,367
11.07.2024, 14:31 7
Igor3D,

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
#include <memory>
#include <cassert>
 
struct SomeData
{
    
};
 
struct SomeObject
{
    std::shared_ptr<SomeData> m_data;
};
 
int main()
{
    //вот есть объект
    SomeObject* object=new SomeObject;
    object->m_data=std::make_shared<SomeData>();
    
    //вот ссылки на его данные
    std::weak_ptr<SomeData> p1=object->m_data;
    std::weak_ptr<SomeData> p2=object->m_data;
    
    //проверяем, что ссылки не протухшие
    assert(!p1.expired());
    assert(!p2.expired());
    
    //к данным можно слазить так
    if(auto shr=p1.lock())
    {
        //shr->;
    }
    
    //а теперь объект прибиваем
    delete std::exchange(object,nullptr);
    
    //убеждаемся, что ссылки протухли
    assert(p1.expired());
    assert(p2.expired());
}
0
1873 / 770 / 108
Регистрация: 01.10.2012
Сообщений: 4,180
11.07.2024, 19:43  [ТС] 8
Алексей1153, если Вы хотели показать связку shared + weak, то лучше так
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
#include <memory>
#include <cassert>
 
struct SomeData
{
    int m_value = 1;
};
 
struct SomeObject
{
    std::weak_ptr<SomeData> m_data;
};
 
int main()
{
    std::shared_ptr<SomeData> data(new SomeData);
    
    SomeObject * object = new SomeObject;
    object->m_data = data;
    
    printf("m_value = %d\n", object->m_data.lock()->m_value);
 
    data.reset();
 
    assert(object->m_data.expired());
    return 0;
}
Но это всего лишь валидность указателя, о чем не раз уже говорилось начиная со стартового поста. Напр перед удалением SomeData необходимо записать данные для undo, так чтобы object опять ссылался на восстановленный SomeData. Ваши действия ?
0
фрилансер
5846 / 5376 / 1103
Регистрация: 11.10.2019
Сообщений: 14,367
11.07.2024, 19:52 9
Цитата Сообщение от Igor3D Посмотреть сообщение
необходимо записать данные для undo
это обеспечивается инкапсуляцией данных внутри SomeObject. Метод, меняющий данные, сохраняет изменения в журнал, затем меняет данные

ни про какие оживающие ссылки и указатели тут думать не приходится. Только адресация в виде (например) целочисленных идентификаторов
0
1873 / 770 / 108
Регистрация: 01.10.2012
Сообщений: 4,180
11.07.2024, 19:56  [ТС] 10
Цитата Сообщение от Алексей1153 Посмотреть сообщение
это обеспечивается инкапсуляцией данных внутри SomeObject. Метод, меняющий данные, сохраняет изменения в журнал, затем меняет данные
ни про какие оживающие ссылки и указатели тут думать не приходится. Только адресация в виде (например) целочисленных идентификаторов
А как выскочить на SomeObject (и на какой) если удаляется SomeData?

Не по теме:

Не спешите с ответами, никто не гонит, обо всем успеем поговорить :)

0
фрилансер
5846 / 5376 / 1103
Регистрация: 11.10.2019
Сообщений: 14,367
11.07.2024, 20:37 11
Igor3D, я же не знаю, что происходит в программе.

Нужно организовать всю структуру данных так, чтобы о любом внесении любых изменений был строгий отчёт в любом виде - лог, журнал, полная история изменений и тому подобное.

Всё это нужно запланировать и спроектировать. Само по себе это не заработает

Добавлено через 4 минуты
например, в простых игрушках я делал такой журнал максимально просто - сохранение всего игрового поля в стеке do/undo.

Такое же получалось проворачивать в рисовалках схем, ОЗУ не жмёт, в json всё сохранял.

но когда такое невозможно (сильно жрётся озу или по иным причинам), сохраняются отдельные действия (как в МС Ворд) - ввод строки, ввод буквы, назначение форматирования, удаление и так далее. Этот журнал изменений откатывается и накатывается при необходимости.

Случай с полным сохранением всех данных позволяет лучше избежать ошибок.
Случай с журналом более сложный, накосячить там легче
0
1873 / 770 / 108
Регистрация: 01.10.2012
Сообщений: 4,180
12.07.2024, 18:36  [ТС] 12
Цитата Сообщение от Алексей1153 Посмотреть сообщение
я же не знаю, что происходит в программе.
Вот нужно удалить SomeData обеспечив undo. Как писать undo - большая тема, но по-любому нужно иметь/знать объекты которые изменились (и обычно что изменилось). В данном случае это не только удаляемый SomeData, но и все SomeObject что ссылаются на него. Вот я и спрашиваю: а как искать этих "клиентов"? Это в простом примере выше с одной переменной все ясно, а в общем случае?

Заметим что использование вумных указателей никак не решает эту проблему, максимум можно получить счетчик "слабых" ссылок. А вот забот "вумничание" уже добавляет, удаление шареного SomeData не гарантируется.

Также интересно как это с точки зрения др языков? Может это лишь заботы "низкоуровневых" плюсов где нет "сборщика мусора" (мечты поэта)? Что скажет прогрессивное ФП?
0
Модератор
Эксперт функциональных языков программирования
3077 / 2226 / 462
Регистрация: 26.03.2015
Сообщений: 8,626
13.07.2024, 01:08 13
Зависит от физического смысла SomeObject и SomeData.

SomeData - это объект или значение? Если объект, то как относятся друг к другу SomeObject и SomeData?
Кто создаёт SomeObject и SomeData?
Может ли меняться SomeData за время жизни SomeObject? Если может, то как?
0
1873 / 770 / 108
Регистрация: 01.10.2012
Сообщений: 4,180
13.07.2024, 01:43  [ТС] 14
Цитата Сообщение от Shamil1 Посмотреть сообщение
Зависит от физического смысла SomeObject и SomeData.
SomeData - это объект или значение? Если объект, то как относятся друг к другу SomeObject и SomeData?
Кто создаёт SomeObject и SomeData?
Может ли меняться SomeData за время жизни SomeObject? Если может, то как?
Смысл может быть очень всяким. Напр SomeObject и SomeData могут быть объектами одного типа, это стандартная техника управления множественными объектами. Напр источников света в сцене может быть довольно много (десятки и сотни). Менять параметры каждого утомительно для юзера. Поэтому он назначает один из источников "мастером" и много источников "слейвами", что будут юзать установки мастера вместо собственных. Создание/удаление обычно независимо. Стандартное отношение парент-чайлд тоже в теме, но в общем случае никаких др отношений между SomeObject и SomeData может и не быть и никто из них другим не владеет. И да, SomeData может меняться за время жизни SomeObject, который, возможно, обязан на это реагировать.
0
Модератор
Эксперт функциональных языков программирования
3077 / 2226 / 462
Регистрация: 26.03.2015
Сообщений: 8,626
13.07.2024, 02:53 15
Цитата Сообщение от Igor3D Посмотреть сообщение
SomeData может меняться за время жизни SomeObject, который, возможно, обязан на это реагировать.
Событие "меня удаляют", на которое можно подписаться?
0
1873 / 770 / 108
Регистрация: 01.10.2012
Сообщений: 4,180
13.07.2024, 03:06  [ТС] 16
Цитата Сообщение от Shamil1 Посмотреть сообщение
Событие "меня удаляют", на которое можно подписаться?
Тот же тест/пример: undo. Как "восстановить переписку"?
0
6340 / 3511 / 1427
Регистрация: 07.02.2019
Сообщений: 8,977
13.07.2024, 10:20 17
Цитата Сообщение от Igor3D Посмотреть сообщение
Вот нужно удалить SomeData обеспечив undo. Как писать undo - большая тема, но по-любому нужно иметь/знать объекты которые изменились (и обычно что изменилось). В данном случае это не только удаляемый SomeData, но и все SomeObject что ссылаются на него. Вот я и спрашиваю: а как искать этих "клиентов"?
Не понимаю, что нужно искать. do/undo обычно реализуется через паттерн "команда". Команда(или "исполнитель") знает, как применить действие, как сериализовать и отменить, а организованны они в виде стека.
undo не может просто взять и удалить SomeData, т.к. не могло быть просто команды "добавить SomeData", тем более добавление не могло быть после появления ссылок у объектов SomeObject на него. Сначала отменяются команды, которые создали ссылки и только потом команда, создавшая SomeData.
Короче, вы высасываете проблему из пальца. А если нет, то приведите наиболее приближенный пример(модель, реализованную в коде), демонстрирующий вашу проблему.
0
1873 / 770 / 108
Регистрация: 01.10.2012
Сообщений: 4,180
13.07.2024, 17:33  [ТС] 18
Цитата Сообщение от zayats80888 Посмотреть сообщение
Короче, вы высасываете проблему из пальца. А если нет, то приведите наиболее приближенный пример(модель, реализованную в коде), демонстрирующий вашу проблему.
Юзер указал что источник Light2 будет использовать параметры Light1 (см детали выше), сохранил изменения и продолжает работу. Через недельку он пришел к выводу что Light1 не нужен и удаляет его. Какие тут "команды"? Этот поезд давно ушел

Не по теме:

Антипаттерны гораздо полезнее паттернов :)

0
фрилансер
5846 / 5376 / 1103
Регистрация: 11.10.2019
Сообщений: 14,367
13.07.2024, 17:36 19
Igor3D, либо запретить удаление, если на объект есть ссылка, либо Light2 будет использовать дефолты
0
6340 / 3511 / 1427
Регистрация: 07.02.2019
Сообщений: 8,977
13.07.2024, 17:40 20
Цитата Сообщение от Igor3D Посмотреть сообщение
Через недельку он пришел к выводу что Light1 не нужен и удаляет его.
А каким боком вы сюда undo приплели?

Добавлено через 2 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
Юзер указал что источник Light2 будет использовать параметры Light1
Архитектурно напрашивается, что параметры это ресурс, т.е. подсчет ссылок актуален.
0
13.07.2024, 17:40
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.07.2024, 17:40
Помогаю со студенческими работами здесь

Указатель на функцию член
Вот урезаный донельзя код: class Window { public: ... bool registerClassEx()

Указатель на функцию-член
Доброго времени суток, возникла следующая ситуация: Приведу пример: class A { public: void a()...

Указатель на функцию-член
Имеем следующий код: #include &lt;iostream&gt; using namespace std; class Windows { public: void...

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

Статический член указатель на класс
Доброго времени суток. Что требовалось: создать статический указатель на класс CPerson, чтобы...

Указатель на функцию-член класса
Нужно передать указатель на функцию класса A изнутри самого класса А в функцию, в качестве...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru