Russian Qt Forum
Ноябрь 23, 2024, 18:05 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Оператор [] вместо get/set [РЕШЕНО]  (Прочитано 9193 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Апрель 13, 2012, 12:14 »

Добрый день

Есть структура с методами get/set

Код
C++ (Qt)
struct CArray {
...
int Get( size_t index ) const;
void Set( size_t index. int val );
};
 
Хотелось бы иметь возможность писать так
Код
C++ (Qt)
CArray arr;
..
for (int i = 0; i < limit; ++i)
if (arr[i] < 0) arr[i] = 0;
 
Ссылки на int я не имею, понимаю что не могу взять адрес от такого "элемента" - ничего, обойдусь, мне бы просто присваивание удобно писать в стиле массива, а не размазывать set. Как это сделать?

Спасибо
 
« Последнее редактирование: Апрель 13, 2012, 18:14 от Igors » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #1 : Апрель 13, 2012, 12:34 »

А как у Вас set и get реализованы?

И что значит:
Цитировать
Ссылки на int я не имею, понимаю что не могу взять адрес от такого "элемента"...
?
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Bepec
Гость
« Ответ #2 : Апрель 13, 2012, 12:48 »

Эммм... а что мешает оператор индексации переопределить?

И что скрывается за ... в структуре? В чём хранишь значения?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Апрель 13, 2012, 14:22 »

А как у Вас set и get реализованы?
И что скрывается за ... в структуре? В чём хранишь значения?
Да все что угодно, важно что "не int", поэтому переопределить [] по известным образцам я не могу, т.к. не на что вернуть ссылку. Напр

Код
C++ (Qt)
void CArray::Set( size_t index, int val )
{
mReal[index] = double(val);  // mReal, mImage - контейнеры double
mImage[index] = 0.0;
}
 
Записан
Blackwanderer
Гость
« Ответ #4 : Апрель 13, 2012, 14:33 »

тут без set'а не получится: нужно присваивать двум переменным за раз.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #5 : Апрель 13, 2012, 14:36 »

тут без set'а не получится: нужно присваивать двум переменным за раз.
Да в принципе можно) Только это будет совсем не тривиально и как законный вопрос - оно вообще надо?

Другой вариант..
Организовать массив с элементами std::complex<double>... Хотя, наверно это предлагать бесполезно) Потом выясниться, что там вообще всё что угодно может быть.. и .т.д. и т.п. )
« Последнее редактирование: Апрель 13, 2012, 14:40 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
ddrtn
Гость
« Ответ #6 : Апрель 13, 2012, 14:39 »

Код:
class CArray 
{
...............
int operator[] (size_t idx) const;
int& operator[] (size_t idx);
...............
};
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #7 : Апрель 13, 2012, 14:45 »

Код:
class CArray 
{
...............
int operator[] (size_t idx) const;
int& operator[] (size_t idx);
...............
};
И как это Igors до такого сразу не догадался?  Улыбающийся
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
sudo
Гость
« Ответ #8 : Апрель 13, 2012, 14:55 »

Я тут набросал примитивный вариантик Улыбающийся

Код
C++ (Qt)
#include <QCoreApplication>
#include <QDebug>
 
 
struct Array
{
int get(size_t /*index*/) const { return 0; }
void set(size_t /*index*/, int /*val*/) {}
 
int& operator[](int index);
QList<int> m_list;
};
 
 
int& Array::operator[](int index)
{
 return m_list[index];
}
 
 
int main(int argc, char *argv[])
{
 QCoreApplication a(argc, argv);
 
 Array array;
 array.m_list << 1 << 2 << 3 << 4 << 5 << 6 << 7;
 
 qDebug() << array[2];
 
 array[2] = 100500;
 
 qDebug() << array[2];
 
 return a.exec();
}
 
 

Только на интах, а не на сайз_т, как-то само так получилось Веселый Ну и с проектом не заморачивался
« Последнее редактирование: Апрель 13, 2012, 14:57 от sudo » Записан
sudo
Гость
« Ответ #9 : Апрель 13, 2012, 14:59 »

А как у Вас set и get реализованы?
И что скрывается за ... в структуре? В чём хранишь значения?
Да все что угодно, важно что "не int", поэтому переопределить [] по известным образцам я не могу, т.к. не на что вернуть ссылку. Напр

Код
C++ (Qt)
void CArray::Set( size_t index, int val )
{
mReal[index] = double(val);  // mReal, mImage - контейнеры double
mImage[index] = 0.0;
}
 

А вот с таким что делать, надо думать...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Апрель 13, 2012, 15:05 »

Код:
class CArray 
{
...............
int operator[] (size_t idx) const;
int& operator[] (size_t idx);
...............
};
Мил-человек, разговор с глухими утомляет. Третий раз говорю - НЕТ (отсутствует) у структуры int на который можно вернуть ссылку.

...и как законный вопрос - оно вообще надо?
Ну я же Вас не спрашиваю, зачем/кому нужна Ваша реализация слот/сигнал. Потому что понимаю что интересно "как это сделать", а применения найдутся (обычно уже есть)

Никто не утверждает что так "надо делать". Но есть случаи когда такая конструкция была бы удобной/полезной. Особенно при шаблонизировании (столь любимом некоторыми из нас)

Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #11 : Апрель 13, 2012, 15:27 »

Всё гениальное - просто)

Код
C++ (Qt)
class adapter
{
public:
   adapter(int& tmp, double& re, double& im )
       : m_tmp(tmp), m_re(re), m_im(im) {}
   int& value() { return m_tmp; }
   ~adapter() {
       m_re = m_tmp;
       m_im = 0.0;
   }
private:
   int& m_tmp;
   double& m_re;
   double& m_im;
};
 
struct CArray
{
   CArray() {}
 
   int& operator[](size_t index) {
       double& re = mReal[index];
       double& im = mReal[index];
       adapter adap(m_tmp, re, im);
       return adap.value();
   }
 
   enum {SIZE = 100};
   double mReal[SIZE];
   double mImag[SIZE];
   int m_tmp;
};
 
int main()
{
   CArray arr;
   arr[1] = 2;
   std::cout << arr[1] << std::endl;
   return 0;
}
 
Это для записи. Для чтения почти аналогично пишется)
« Последнее редактирование: Апрель 13, 2012, 15:30 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #12 : Апрель 13, 2012, 16:51 »

Да, сорри) Мой вариант выше - это плохое решение(( Так делать нельзя(
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
kamre
Частый гость
***
Offline Offline

Сообщений: 233


Просмотр профиля
« Ответ #13 : Апрель 13, 2012, 17:52 »

Как это сделать?

Можно через промежуточный класс:
Код:
#include <iostream>

class CArray {
public:
  int get(int index) const {
    int res = (index & 1) ? 1 : -1;
    std::cout << "get(" << index << ") = " << res << std::endl;
    return res;
  }
  void set(int index, int value) {
    std::cout << "set(" << index << ", " << value << ")" << std::endl;
  }

  struct Helper {
    CArray& a;
    int i;
    Helper(CArray& _a, int _i) : a(_a), i(_i) {}
    Helper& operator=(int value) { a.set(i, value); return *this; }
    operator int() { return a.get(i); }
  };

  Helper operator[](int index) { return Helper(*this, index); }
};

int main()
{
  CArray arr;
  for (int i = 0; i < 10; ++i) {
    if (arr[i] < 0) arr[i] = 0;
  }
  return 0;
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Апрель 13, 2012, 18:14 »

Можно через промежуточный класс:
Все четко. Спасибо
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.367 секунд. Запросов: 23.