Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перегрузка оператора индексации [] 
:(
    Опции темы
lega4
Дата 4.5.2011, 09:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 19.12.2010

Репутация: нет
Всего: нет



Имеется некоторый класс почти массив. "Почти" - потому что элементы лежат в памяти не по байтам, а по битам и, соответственно, для установки значений и получения значений элементов реализованы специальные функции.
Требуется перегрузить [] так, чтобы:
1. Можно было просто написать unsigned j=myclassvar["abc"], где myclassvar - переменная моего класса, "abc" - название "поля". С этой задачей я справился без проблем, т.к. есть функция возврата значения нужного поля.
2. И чтобы работал такой код myclassvar["abc"]=4;
Собственно, со вторым пунктом проблемы. Когда в классе используются встроенные типы данных, то достаточно возвращать ссылку на требуемый элемент класса и все прокатит. А тут непонятно как... Подскажите, пожалуйста.

Это сообщение отредактировал(а) lega4 - 4.5.2011, 10:19
PM MAIL   Вверх
kosmonaFFFt
Дата 4.5.2011, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Перегрузи [] так, чтобы он возвращал ссылку... Ради примера можешь посмотреть в исходники STL, класс vector или list...


--------------------
user posted image
PM MAIL ICQ   Вверх
lega4
Дата 4.5.2011, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 19.12.2010

Репутация: нет
Всего: нет



kosmonaFFFt, и вы не поняли вопроса. У меня элементы располагаются побитово. Мне не нужно возвращать весь байт, нужно только нужное поле. Функции для записи и чтения полей уже есть.
PM MAIL   Вверх
bsa
Дата 4.5.2011, 10:19 (ссылка) |    (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



lega4, для этого используют прокси-классы. Т.е. оператор [] твоего класса возвратит объект некого прокси-класса, у которого определен оператор присваивания. Этот оператор уже установит нужный бит в основном классе:
Код
class BitMap
{
public:
    class Proxy {
    public:
       Proxy& operator=(unsigned value) { base_.assign(field_, value); return *this; }
       operator unsigned() const { return base_.get(field_); }
    private:
       BitMap &base_;
       const char *field_;
       Proxy(BitMap &base, const char *field) : base_(base), field_(field) {}
       Proxy(const Proxy&); //disable copy constructor
       Proxy& operator=(const Proxy&); //disable copy operator
       friend class BitMap;
    };
    Proxy operator[](const char *field) { return Proxy(*this, field); }
    unsigned operator[](const char *field) const { return get(field); }
private:
    void assign(const char *field, unsigned value) { ... }
    unsigned get(const char *field) const { ... }
};


Это сообщение отредактировал(а) bsa - 4.5.2011, 10:24
PM   Вверх
alexvs11
Дата 4.5.2011, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 2
Всего: 10



std::bitset  же есть
PM MAIL   Вверх
lega4
Дата 4.5.2011, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 19.12.2010

Репутация: нет
Всего: нет



bsa, была такая идея, но что-то я ее сразу отмёл, думал, есть способ элегантнее...
Спасибо за пример, написал, теперь индексация работает как надо. 

Еще хотелось бы перегрузить и другие операторы, например плюс. 
Я сделал Proxy с полями: адрес "родительского" объекта основного класса, имя поля, unsigned значение поля (Чтобы не лазить каждый раз в родительский объект и еще кой для чего). Для удобности сделал преобразование в unsigned и из unsigned. Подумал, что с учетом преобразований хватит operator+ (const Proxy&) как члена класса.
Но тогда на выражение типа a["d"]=a["c"]+5; MSVS ругается, мол, непонятно, какой перегруженный оператор вызывать. Если добавить operator+(unsigned), то все равно ругается... Хотелось бы сделать так, чтобы такие выражения считались без явных приведений типа...
Формально вопрос - можно ли указать "приоритет" преобразований типа? Т.е. как в стандартных типах int+double - вопроса не возникнет (Хотя и int можно привести к double, и double к int) - все аргументы приведутся к "старшему" типу (double). Можно ли в своем классе указать "старшинство" типа? Например, считать мой класс самым главным - если он встречается в выражении, но все аргументы будут приводится к нему, а не наоборот.

Это сообщение отредактировал(а) lega4 - 4.5.2011, 22:18
PM MAIL   Вверх
mes
Дата 4.5.2011, 23:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



для начала покажите как у Вас сделано.. 



--------------------
PM MAIL WWW   Вверх
borisbn
Дата 5.5.2011, 06:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



> a["d"]=a ["c"]+5;
IMHO не стОит увлекаться перегрузкой операторов. Такой код, как это не парадоксально, менее читаемый, чем вызов функции 


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
lega4
Дата 5.5.2011, 06:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 19.12.2010

Репутация: нет
Всего: нет



mes, вроде все и без примера должно быть ясно 
Код
class Myclass
{
public:
Myclass(unsigned);
operator unsigned();
friend Myclass operator+(const Myclass&, const Myclass&);
....
}

Выражение типа 
Код

Myclass a;
a+5;

Если подумать, то и правда неоднозначно:
1. Можно трактовать как (unsigned)a +5;
2. А можно a+myclass(5);

borisbn, по-моему, в таком виде это вполне нормально. Все читаемо)) 
А на самом деле, это задача не практическая, а учебная, так что практичности не требуется)

Это сообщение отредактировал(а) lega4 - 5.5.2011, 06:19
PM MAIL   Вверх
mes
Дата 5.5.2011, 08:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(lega4 @  5.5.2011,  05:15 Найти цитируемый пост)
 вроде все и без примера должно быть ясно 

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

а зачем нужен оператор +, если уже есть преобразование к unsigned ?


--------------------
PM MAIL WWW   Вверх
borisbn
Дата 5.5.2011, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(lega4 @  5.5.2011,  06:15 Найти цитируемый пост)
в таком виде это вполне нормально. Все читаемо

Это сейчас (через пару дней после написания) читаемо и читаемо тобой. Другому человеку, чтобы понять, что делается здесь - a["d"]=a ["c"]+5 - нужно будет либо в твою документацию, либо в исходники лазать.

Цитата(lega4 @  5.5.2011,  06:15 Найти цитируемый пост)
А на самом деле, это задача не практическая, а учебная, так что практичности не требуется

С учебной точки зрения уметь перегружать операторы, конечно, нужно, но с практической точки зрения этого лучше не делать. Посмотри, к примеру, STL (его даааалеко не глупые люди писали). Там если и перегружают операторы, то самое очевидное и минимально необходимое (собственно [] и << с >>)


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
alexvs11
Дата 5.5.2011, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 2
Всего: 10



Цитата(borisbn @  5.5.2011,  10:31 Найти цитируемый пост)
Посмотри, к примеру, STL (его даааалеко не глупые люди писали). Там если и перегружают операторы, то самое очевидное и минимально необходимое (собственно [] и << с >>)

в стандартной библиотеке еще есть перегрузка ! для потоков
PM MAIL   Вверх
bsa
Дата 5.5.2011, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



самая опасная перегрузка - перегрузка операторов преобразования. Этого стоит избегать любыми средствами. То что я привел пример такой, это не значит, что именно так надо делать.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0529 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.