Перейти к содержанию
    

Плавный переход C -> C++ под МК

22 минуты назад, juvf сказал:

Задача про которую говорит  jcxz - обработать много данных класса за раз (когда нужно однотипно обработать несколько членов класса).

И в чем преимущество? При "перестройке" указателя на другой член будет строчка писанины, преимуществ не видно.

Да, если нужно сослаться на мембер класса, то указатель будет вот этой специфичной формы.

Преимущество указателей на мемберы удобно как раз при применении к разным объетам класса, а не к одному и тому же, т.к. в таком случае профит ровно такой же, как от прямых записей в стиле

for(u32 i = 0; i < size; ++i) {
  led.red = 0;
  led.green = 0;
  led.blue = 0;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, Arlleex сказал:

И в чем преимущество? При "перестройке" указателя на другой член будет строчка писанины, преимуществ не видно.

Какого указателя? Ну чтобы его перестроить куда-то, он должен быть. Значит нужен.
Или я не понял смысл вашей фразы.

6 минут назад, Arlleex сказал:

Преимущество указателей на мемберы удобны как раз при применении к разным объетам класса, а не к одному и тому же

Естественно не одному. Вроде и в примерах я так приводил.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

  

7 minutes ago, jcxz said:

Начните уже думать наконец!

Начните сначала примеры приводить, а уже потом по привычке хамить. Именно в таком порядке. Все от этого только выиграют.

 

7 minutes ago, jcxz said:

Если есть члены класса: x1, x2, x3, x4, x5, x6, x7, x8, x9. Но цикл должен пройтись только по: x1, x3, x5, x9?
Как их объединить в массив?

Объединить в массив - это такая необходимая цель или можно без этого обойтись?

 

Члены класса прекрасно проходятся по списку, индексы могут быть вычисляемыми (например только четные) или его индексы могут быть вообще заданы в const-массиве, а пройдя по списку этого массива достаточно получить индексы массива поля класса, где и даже на что можно поменять. Так называемые lut таблицы.

Я так делал без всяких указателей, явно и очень читаемо.

реально не пойму, зачем тут нужны указатели?

давайте конкретно - покажите пример, где видно их явное преимущество, вот ну никак без них, прям получется не код а кошмар

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

30 минут назад, juvf сказал:

Можно убрать шаблон для uint и сделать отдельную функци, тогда вы измените API

понятно

21 минуту назад, Arlleex сказал:

Вроде мой пример вполне показывает минималистичный кейс, в котором +/- понятна идея этих указателей.

21 минуту назад, Forger сказал:

можете привести КОНКРЕТНЫЙ пример, где указатель прям вот очень нужен и без него ничего путного не получается?

А разве всякие GUI - это не конкретный пример. Например Qt состоит обычно GUI состоит чуть менее, чем полностью из членов-указателей. Указатель на парент, указатель на child. В GUI указатели на всякие next, prev, .... у главного окна может быть массив детей (массив указателей на Widget), и надо всем дать команду отрисовки - по массиву указателей всех перебрал. А может на главном окне 2 кнопоки и 2 лейбы, у главного окна только один указатель на child (пусть будет кнопка1), а у этой кнопки1 указатель next на кнопку2, у кнопки 2 указатель next на лейбу1, у лейбы1 next указывает на лейбу2,  у лейбы2 next =0; Главное окно вызывает у child->repaint(), т.е. у кнопки1, кнопка1 в своем методе вызовит repaint у своего child, а потом проверит, если next != 0, то вызовит next->repaint();  И так произойдет repaint всех детей главного окна включая внуков, правнуков и все родовое дерево до последнего младенца.

 

тоже самое при удалении (о чем говорил jcxz). Так же можно открепить чаилда (созданого динамически в какойнить фабрике) и передать другому родителю.... это с указателями это делается. 

Изменено пользователем razrab83

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

21 минуту назад, Forger сказал:

Объединить в массив - это такая необходимая цель или можно без этого обойтись?

Вы издеваетесь?? Объединить в массив - это вы предложили. Я же уже 100500 раз сказал что: не всегда можно обрабатываемые однотипно данные объединить в массив. И конкретные примеры привёл.

21 минуту назад, Forger сказал:

Члены класса прекрасно проходятся по списку, индексы могут быть вычисляемыми (например только четные) или его индексы

НЕТ ИНДЕКСОВ. нет массива членов == нет индексов. Члены - несмежные.

21 минуту назад, Forger сказал:

реально не пойму, зачем тут нужны указатели?

давайте конкретно - покажите пример, где видно их явное преимущество, вот ну никак без них, прям получется не код а кошмар

Уже несколько примеров привёл. Это ж как можно их не заметить???  :unknw:

PS: Всё ясно. "Чукча не читатель - чукча писатель".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

24 минуты назад, jcxz сказал:

Какого указателя? Ну чтобы его перестроить куда-то, он должен быть. Значит нужен.
Или я не понял смысл вашей фразы.

Ды я уже понял, что Вы имели в виду случай, когда указатели на конкретные члены уже распихнуты в некий массив. И их позиция не меняется.

А я (как в упрощенном случае задания цвета светодиодов) имел в виду следующие преимущества указателей.

В случае, если бы указателей таких не существовало, мы должны были бы написать нечто такое

void changeBalanceRed(Led leds[], u8 value) {
  for (auto i = 0; i < MAX_LEDS_QNT; ++i)
    leds[i].red = value;
}

void changeBalanceGreen(Led leds[], u8 value) {
  for (auto i = 0; i < MAX_LEDS_QNT; ++i)
    leds[i].green = value;
}

void changeBalanceBlue(Led leds[], u8 value) {
  for (auto i = 0; i < MAX_LEDS_QNT; ++i)
    leds[i].blue = value;
}

int main() {
  u8 value = ...; // get_new_value()
  
  if (...)
    changeBalanceRed(LedArray, value);
  else if (...)
    changeBalanceGreen(LedArray, value);
  else
    color = changeBalanceBlue(LedArray, value);
}


Т.е. мне пришлось бы создавать отдельные функции для доступа к каждому отдельному члену.

А в таком случае функция - одна, общая

Спойлер
7 часов назад, Arlleex сказал:

Возможно для однотипного изменения какого-то элемента в целом списке объектов, но когда заранее точно не известно, какой мембер надо менять. Чтобы кучу if() не писать, а возложить все на компилятор.

В голову пример такой пришел. Есть панель с подсветкой, подсветка из отдельных управляемых RGB-светодиодов. Каждый диод описывается как

class Led {
  public:
    u8 red, green, blue;
  ...
};


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

void changeBalance(Led leds[], u8 Led::*color, u8 value) {
  for (auto i = 0; i < MAX_LEDS_QNT; ++i)
    leds[i].*color = value;
}


Ну а в точке принятия решения, какой цвет будем менять

u8 Led::*color;

if (...)
  color = &Led::red;
else if (...)
  color = &Led::green;
else color = &Led::blue;

u8 value = ...; // get_new_value()

changeBalance(LedArray, color, value);


В принципе, необходимость таких указателей понятна.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, razrab83 сказал:

А разве всякие GUI - это не конкретный пример. Например Qt состоит обычно GUI состоит чуть менее, чем полностью из членов-указателей. Указатель на парент, указатель на child. В GUI указатели на всякие next, prev, .... у главного окна может быть массив детей (массив указателей на Widget), и надо всем дать команду отрисовки - по массиву указателей всех перебрал.

Да, именно так. Как раз тоже хотел привести пример с GUI, но было лень писать много буков.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 минут назад, razrab83 сказал:

понятно

А разве всякие GUI - это не конкретный пример. Например Qt состоит обычно GUI состоит чуть менее, чем полностью из членов-указателей. Указатель на парент, указатель на child. В GUI указатели на всякие next, prev, .... у главного окна может быть массив детей (массив указателей на Widget), и надо всем дать команду отрисовки - по массиву указателей всех перебрал. А может на главном окне 2 кнопоки и 2 лейбы, у главного окна только один указатель на child (пусть будет кнопка1), а у этой кнопки1 указатель next на кнопку2, у кнопки 2 указатель next на лейбу1, у лейбы1 next указывает на лейбу2,  у лейбы2 next =0; Главное окно вызывает у child->repaint(), т.е. у кнопки1, кнопка1 в своем методе вызовит repaint у своего child, а потом проверит, если next != 0, то вызовит next->repaint();  И так произойдет repaint всех детей главного окна включая внуков, правнуков и все родовое дерево до последнего младенца.

А Вы точно имеете в виду указатели на мемберы, а не обычные указатели на объекты классов?
 

6 минут назад, jcxz сказал:

Я же уже 100500 раз сказал что: не всегда можно обрабатываемые однотипно данные объединить в массив. И конкретные примеры привёл.

Ладно, допустим. А каким образом смежные данные обработать однотипно?

Прибавлять/отнимать от этого самого указателя? А так можно? ИМХО, такое не очень надежно, особенно когда появится не обычный класс, а с каким-нить ромбовидным наследованием.

Я думаю, даже смежные элементы (кроме элементов массивов) нужно по-адресно запихивать в массив указателей на данные класса и по ним прогонять алгоритм.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 минут назад, Arlleex сказал:

Т.е. мне пришлось бы создавать отдельные функции для доступа к каждому отдельному члену.

 

Именно так.

11 минут назад, Arlleex сказал:

Ладно, допустим. А каким образом смежные данные обработать однотипно?

Объединить в массив, кэп.  :wink:

Но можно и через указатели на члены. Если хочется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 минуты назад, jcxz сказал:

Именно так.

Объединить в массив, кэп.  :wink:

Понял. Для меня было

class A {
  int a;
  float b;
};

-> смежные данные, т.к. идут друг за другом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 minutes ago, jcxz said:

НЕТ ИНДЕКСОВ. нет массива членов == нет индексов. Члены - несмежные.

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

При этом если работать с полями классически, то достаточно просто явно заполнить их нужными значениями.

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

 

13 minutes ago, jcxz said:

Пройдя циклом по указателям на члены. Делаю так постоянно.

Это обычная C-гуи? или некая самописная?

Коли так тут любые методы хороши, лишь бы они работали. Но строго в пределах класса, где объявлены и используются строго внутри него.

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

Мало конкретики. Покажите наконец вот прямо код, чтобы отпали все вопросы.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 минуты назад, Arlleex сказал:

А Вы точно имеете в виду указатели на мемберы, а не обычные указатели на объекты классов?

class MyWidget
{
public:
MyWidget(MyWidget *parent_ = nullptr)
{
next = nullptr;
child = nullptr;
prev = nullptr;
if(parent_)
{
	parent = parent_;
	parent->addChild(this);
}
}

virtual void paint()
{
	//код рисования самого себя? т.е. MyWidget-а
	{
	}
	
	if(child != nullptr)
		child->paint();
	if(next != nullptr)
		next->paint();
}

/*private: много писанины с приватом, пусть будет протект*/
protect:
MyWidget *next;
MyWidget *child;
MyWidget *prev;
MyWidget *parent;

}

//ну и наследуемся
class Label : public MyWidget
{
public:
Label(MyWidget *parent_ = nullptr)
	:MyWidget(nullptr)

	void paint() override
	{
		//код рисования самого себя? т.е. Label-а
		{
		}

		MyWidget::paint();

	}
}

не очень понял что занчит "мемберы" и "обычные указатели". Но мой пример - это не то?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

20 minutes ago, Arlleex said:

В случае, если бы указателей таких не существовало, мы должны были бы написать нечто такое

достаточно просто дополнить класс Led методами  changeBalanceRed и т.д., и в одном цикле все поменять.

Если в классе нет методов, то это как правило просто структура/union. И тогда к ней так и нужно относиться, указатели на ее поля тут точно будут лишними )

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 минуты назад, razrab83 сказал:

не очень понял что занчит "мемберы" и "обычные указатели". Но мой пример - это не то?

Неа) Указатели на мемберы - т.е. указатели на члены данных/функции, это не обычные классические указатели.

Это штука вида (для данных и методов класса, соответственно)

type class_name::*pointer_data_member_name;
return_type (class_name::*pointer_func_member_name)();

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

20 минут назад, jcxz сказал:

например можно скрыть или запретить часть виджетов, в зависимсти от значения какого-то члена.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...