Russian Qt Forum

Программирование => С/C++ => Тема начата: Igors от Январь 06, 2021, 13:03



Название: Адресная арифметика
Отправлено: Igors от Январь 06, 2021, 13:03
Добрый день

Есть такая структурка на суровом С
Код:
struct Model {
...
  int m_MaterialCount;
  Material ** m_Materials;
...
}
typedef Material * MaterialPtr;
Возникла необходимость имея MaterialPtr + смещение получить другой как если бы они хранились непрерывным массивом (была бы одна звездочка вместо 2).

Ну а если в рамках "С с классами" это уж никак низзя - можно блеснуть std:: и.т.п. (если конечно оно здесь поможет)

Спасибо


Название: Re: Адресная арифметика
Отправлено: Igors от Январь 08, 2021, 10:52
Все-таки наблюдающийся "отток" людей имеет свои плюсы: по крайней мере нет глупых советов типа
Цитировать
сделай std::vector<Material> и будет тебе счастье
Правда умных советов тоже нет, ну я ничего не потерял :)

Выбрать подходящий контейнер обычно не так уж сложно "с чистого листа", но здесь уже написано немало кода. И даже беглое знакомство с ним показало: решение сделать Material "неперемещаемым" вполне оправдано/грамотно, менять это на вектор не только трудоемко, но просто плохо, не видно как/чем заткнуть полезущие из всех щелей проблемы.

Еще популярный совет
Цитировать
Вот видите, "кривая архитектура" не была продумана с самого начала! Если бы..
Ну т.е. надо так задумывать архитектуру чтобы хорошо ложились новые фичи, что появятся через неск лет! Ну дай бог конечно, но по-моему это уж как повезет.

Однако вернемся к собсно теме. Хорошо или плохо, но новый ф-ционал обеспечить надо, как это сделать?

1) Изменить базовый контейнер так чтобы он поддерживал нужный ф-ционал. Тогда как? (простое std::vector явно не годится)

2) Оставить **, т.е. не пытаться сотворить чудо-контейнер (такого нет в природе), а нового ф-ционала добиться добавлением новых данных, а возможно и доп контейнеров. Лично я считаю что этот путь верный и вовсе не является "костылем". Опять-таки "как"?

Да, и поактивнее, товарищи, надо быть "в тонусе", а не сваливаться в блевотину сборок и андроидов


Название: Re: Адресная арифметика
Отправлено: Old от Январь 08, 2021, 12:52
Сам задаю вопрос, сам даю глупые советы и сам же их ловко отвергаю...
Зачем вам форум, вам нужен блог. :)


Название: Re: Адресная арифметика
Отправлено: Igors от Январь 12, 2021, 11:37
Все равно "дубль-пусто". Почему, ведь вариантов немало, ну хотя бы так
Код
C++ (Qt)
struct Material {
..
Material * m_prev, * m_next;
..
};
Если структуры "неперемещаемые" (а это так), то указатели уплыть не должны. Правда я совершенно не вижу "книжного" решения (вероятно поэтому и ответов нет). Ну что же, бывает и так, попастись на готовом часто выгодно, но не всегда удается. Здесь видимо нет.


Название: Re: Адресная арифметика
Отправлено: Old от Январь 12, 2021, 13:18
Ну что же, бывает и так, попастись на готовом часто выгодно, но не всегда удается. Здесь видимо нет.
Да, к сожалению в 21 веке эта задача не решаема. Будем ждать 22 век, возможно в c++120 что-то появится.


Название: Re: Адресная арифметика
Отправлено: ecspertiza от Январь 12, 2021, 16:06
Разве две звездочки не дают возможности доступа по индексу? Дальше вопрос со смещением, смещение делим на sizeof получаем индекс, только если внутри нет POD типов.


Название: Re: Адресная арифметика
Отправлено: __Heaven__ от Январь 14, 2021, 08:31
сделай std::vector<Material> и будет тебе счастье


Название: Re: Адресная арифметика
Отправлено: __Heaven__ от Январь 14, 2021, 08:37
Звучит просто
1. найти индекс материала в массиве
2. вычислить новый индекс
3. найти материал по новому индексу


Название: Re: Адресная арифметика
Отправлено: Igors от Январь 14, 2021, 12:11
Разве две звездочки не дают возможности доступа по индексу?
Дальше вопрос со смещением, смещение делим на sizeof получаем индекс, только если внутри нет POD типов.
Не дают :) Material * (MaterialPtr) - это адрес структуры, а в контейнере сидит указатель на нее (**). И кстати делить на sizeof можно всегда, хоть POD хоть не POD (указатель на VMT в sizeof входит).

Звучит просто
1. найти индекс материала в массиве
2. вычислить новый индекс
3. найти материал по новому индексу
"А можно пример?" :)

И чтобы С не смущало можно просто
Код
C++ (Qt)
struct Model {
...
 QList<Material> m_materials;
...
};
Все то же самое, я оставил ** чисто из уважения к старому коду


Название: Re: Адресная арифметика
Отправлено: __Heaven__ от Январь 14, 2021, 22:02
Примерно так вижу
Код
C++ (Qt)
MaterialPtr Model::advancedMaterial(MaterialPtr base, int offset) {
   auto pos = std::find(m_Materials, m_Materials + m_MaterialCount, base);
   return pos + offset;
};
 


Название: Re: Адресная арифметика
Отправлено: Igors от Январь 15, 2021, 11:46
Примерно так вижу
Код
C++ (Qt)
MaterialPtr Model::advancedMaterial(MaterialPtr base, int offset) {
   auto pos = std::find(m_Materials, m_Materials + m_MaterialCount, base);
   return pos + offset;
};
 
Так а где ж взять Model? MaterialPtr подается в сотни мест которые о модели ничего не слыхали.

И чмошный find в этой задаче не катится (выжимается скорость)


Название: Re: Адресная арифметика
Отправлено: Old от Январь 15, 2021, 12:26
И чмошный find в этой задаче не катится (выжимается скорость)
Вы бы показали как мамкины настоящие выжимальщики выжимают скорость в таком варианте: :)
Код
C++ (Qt)
struct Model {
...
 int m_MaterialCount;
 Material ** m_Materials;
...
}
 



Название: Re: Адресная арифметика
Отправлено: __Heaven__ от Январь 15, 2021, 14:52
Не, ну можно ещё нечмошным бинарным поиском воспользоваться

А вообще, что спрошено, то и предложено


Название: Re: Адресная арифметика
Отправлено: Igors от Январь 16, 2021, 09:29
Не, ну можно ещё нечмошным бинарным поиском воспользоваться
Все равно оверхед, да и сортировать материалы никто не разрешал

А вообще, что спрошено, то и предложено
Неправда, спрашивалось как по одному материалу найти другой (а вовсе не "как найти эл-т в контейнере")


Название: Re: Адресная арифметика
Отправлено: Igors от Январь 16, 2021, 09:55
Вообще-то мне больше интересен "философский аспект". Вот жил-был какой-то код, не будем смущать звездочками, то же самое в более привычном (для современников) виде
Код
C++ (Qt)
class Model {
..
QList<Material> m_materials;
..  
};
Что тут "не так"? Да все так, Model владеет материалами, каждый материал размещен в куче и неперемещаем, поэтому указатель на него используется повсеместно. Все бычит.

И вот появляется новая фича, у которой материал может "мутировать". Отношения владения при этом никак не меняются, владеет по-прежнему модель.

И вот ЧТО? Я должен немедленно  "менять архитектуру своего приложения" (как говорит научный работник)? Сразу приходит на ум: а еще чего-то понадобится - так что, опять все менять? Что же это за архитектура что рассыпается на первом скачке?

А если не менять, то как обеспечить новую фичу?


Название: Re: Адресная арифметика
Отправлено: Igors от Январь 24, 2021, 12:46
И затухло. А жаль. Проблему-то решил минут за 5, задолго до создания темы. Но как-то уж очень "вызывающе", попираю все прынцыпы и все такое. Вот и решил обсудить - а может есть более грамотное решение? Вспомнилось как, не так уж давно, один товарищ тут контейнер выбирал - аж позавидовал, все должно быть "кошерно", никаких там "приведений" (ну прям не писяет не какает). А другой все на машины двигатели ставил - тоже круто, неправильно не поставишь!

Так существует ли такое совершенство (или так, понты..)  ???