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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с использованием перегруженного [] 
:(
    Опции темы
En_t_end
Дата 13.10.2005, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



В неком классе на основе некого массива есть такой оператор:
Код

class SomeClass
{
//******************************
SomeType *somestor;
SomeType operator[](unsigned long index){return somestor[index]};
//******************************
};

Испытываю проблемы при компиляции... ругается на вот такое:
Код

//*******************Где-то в методе чужого класса...
//*********somestor_cl - обьект класса SomeClass
somestor_cl[someindex].SomeMemb = SomeValue;
//*****

Говорит, что значение может присвоенно быть только переменной, это я и без него знаю(lvalue must be left!) Вот только непонятно почему я не могу присвоить SomeMemb находящемуся в некоторой структуре SomeType значение SomeValue, как надо обращаться в подобных случаях ?
PM MAIL ICQ Skype GTalk Jabber   Вверх
srd
Дата 13.10.2005, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


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

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



У тебя перегруженный оператор возвращает копию, а должен возвращать ссылку.


--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
En_t_end
Дата 13.10.2005, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Точно!!!
Вот она ошибка...
Добавлено @ 11:22
somestor_cl[someindex]->SomeMemb - это во вторых, а
SomeType operator[](unsigned long index){return somestor[index]};
меняем на SomeType* operator[](unsigned long index){return &somestor[index]};
PM MAIL ICQ Skype GTalk Jabber   Вверх
srd
Дата 13.10.2005, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


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

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



А может вместо
SomeType* operator[](unsigned long index){return &somestor[index]};
лучше будет
SomeType& operator[](unsigned long index){return somestor[index]};
и писать потом
somestor_cl[someindex].SomeMemb
smile


--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
En_t_end
Дата 13.10.2005, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



srd
У меня к ссылкам какое-то врожденное недоверие... smile


Добавлено @ 15:20
по мне так лучше возвращать указатель( это из области наглядности, которую мы кстати уже в одной теме обсуждали)
PM MAIL ICQ Skype GTalk Jabber   Вверх
srd
Дата 13.10.2005, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


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

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



Цитата(En_t_end @ 13.10.2005, 23:18)
У меня к ссылкам какое-то врожденное недоверие...

В противном случае ты нарушаешь семантику оператора []. Оператор [], возвращающий указатель на объект вместо ссылки, это как оператор +, который вместо сложения операндов их перемножает.



--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
nikitao
Дата 13.10.2005, 21:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кот-программист
***


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

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



Цитата
У меня к ссылкам какое-то врожденное недоверие...

ПОЧЕМУ????(ИМХО) ЭТО ОЧЕНЬ ОЧЕНЬ УДОБНЫЙ ИНСТРУМЕНТ. smile


--------------------
Жизнь - печальная штука.
PM MAIL ICQ Skype GTalk   Вверх
Earnest
Дата 14.10.2005, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



Цитата(srd @ 13.10.2005, 11:27)
А может вместо
SomeType* operator[](unsigned long index){return &somestor[index]};
лучше будет
SomeType& operator[](unsigned long index){return somestor[index]};


И еще в пару к нему

SomeType operator[](unsigned long index) const {return somestor[index]};

Чтобы совсем было правильно. Это чтобы с константными объектами правильно работалось. И брось на тему ссылок заморачиваться.



--------------------
...
PM   Вверх
maxim1000
Дата 14.10.2005, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата
SomeType operator[](unsigned long index) const {return somestor[index]};

а почему не так:
const SomeType &operator[](unsigned long index) const {return somestor[index]};
?
просто я представил ситуацию:
const SomeType *f(const SomeClass &qqq)
{
return &qqq[1];
}
void g(const SomeClass &qqq)
{
print(*f(qqq));
}

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


--------------------
qqq
PM WWW   Вверх
Earnest
Дата 14.10.2005, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



Можно и так (если объект большой и его не очень хочется возвращать по значению).

А вот твой пример - это не аргумент. Это в равной степени относится к любым стандартным контейнерам STL. И вообще к любой функции, которая возвращает значение, а не ссылку.
Пример:

Код

double getFive() { return 5.0; }

double* very_stupid_func()
{
   return & getFive();
}

Ну и ?

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


--------------------
...
PM   Вверх
srd
Дата 14.10.2005, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


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

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



Я так полагаю, что maxim1000 имел в виду другую проблему:
Код

class S
{
public:
    S(void)
        : a(0)
    {}        
    int operator[](size_t index) const {return a[index];}
    int& operator[](size_t index) {return a[index];}
private:
    int* a;
};

void func(const int* a)
{
    // ...
}

int main(void)
{
    int a[5];
    func(&a[0]);
    
    S s1;
    func(&s1[0]);

    const S s2;
    // Если константый оператор [] возвращает копию, то получаем ошибку компиляции.
    // Заменяем возвращаемое значение оператора на константную ссылку (const int&) и всё ок.
    func(&s2[0]);
    return 0;
}

Кошерные оператор [] должен возвращать ссылку, а константынй оператор [] - константную ссылку.


--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
Earnest
Дата 14.10.2005, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



Не согласна, это пример из той же серии.
Ведь в зависимости от реализации, объект может просто не существовать в памяти, а скажем вычисляться, или еще как-то хитро выковыриваться. Константный опаратор [] должен вызывать нечто, что может быть rvalue, и не обязано иметь адрес. А "кошерный" код не должен закладываться на реализацию. Сегодня я использую массив в памяти (внутри класса), а завтра захочу усложнить реализацию, и все буду хранить, ну не знаю, на соседней машине. Попробуй скажи, что не имею права! И полетит твой код ко всем чертям.
Еще раз повторяю - такие функции просто нельз я писать.


--------------------
...
PM   Вверх
maxim1000
Дата 14.10.2005, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



вот с чем я тут полностью соглашусь, так это с тем, что и та, и та форма может оказаться правильным решением в конкретной ситуации

просто я стараюсь придерживаться того, чтобы при переопределении какого бы то ни было оператора его семантика менялась как можно меньше, и если информации о ситуации недостаточно, я придерживаюсь этого принципа
а взятие адреса поддреживается стандартным []

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

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

что касается вычислимых полей, то даже их неконстантная версия [] не должна возвращать ссылку...


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


Бывалый
*


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

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



Цитата(maxim1000 @ 14.10.2005, 16:57)
просто я стараюсь придерживаться того, чтобы при переопределении какого бы то ни было оператора его семантика менялась как можно меньше, и если информации о ситуации недостаточно, я придерживаюсь этого принципа
а взятие адреса поддреживается стандартным []

Угу. Кроме того зачем нужны лишние расходы на копирование, если можно их избежать?
P.S. Хотя спор о ерунде, ИМХО. smile
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
srd
Дата 14.10.2005, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


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

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



Ну что ж, оператор[], качающий данные с соседней машины - это суровый аргумент smile Впрочем, я остаюсь при своём мнении - поведение перегруженного оператора должно быть максимально похоже на поведение встроенного.


--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
maxim1000
Дата 14.10.2005, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата
Угу. Кроме того зачем нужны лишние расходы на копирование, если можно их избежать?

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


--------------------
qqq
PM WWW   Вверх
GremlinProg
Дата 14.10.2005, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



пожалуй многие согласятся с тем, что кучу перегруженных operator [] лучше заменить на пару:
operator SomeType*(void)
и
operator const SomeType*(void)

просто подумайте, на сколько это удобно
somestor_cl[someindex] - работает
(somestor_cl + someindex)->SomeField - работает
и не надо лишнее писать:return somestor[index]

Ещё один плюс (на мой взгляд - наиболее значимый): в операторе [] - шаблонный класс не сможет выдать подсказку после ".", или "->" при нажатии Ctrl+Space, а в SomeType*(void) - сможет


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
LPBOY
Дата 14.10.2005, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(maxim1000 @ 14.10.2005, 17:22)
не совсем... я думал привести этот аргумент...
тут есть одна тонкость: если поле вычисляемое, в любом случае надо создавать объект, который будет хранить результаты
в случае возврата ссылки единственный способ - создать объект в куче и вернуть ссылку на него (потому как возвращать ссылку на временный объект - просто ужасно), это приведет к путаннице с вопросом "кто и когда должен его удалять, чтобы не было утечки памяти"
в случае вычислимых полей вариант без ссылки действительно лучше...

Я не очень понял что такое "вычислимые поля", а также почему "в любом случае надо создавать объект". Но проблемы никакой тут нет и копировать ничего не надо. И вообще что ты имел в виду smile
Добавлено @ 17:35
Цитата(GremlinProg @ 14.10.2005, 17:24)
пожалуй многие согласятся с тем, что кучу перегруженных operator [] лучше заменить на пару


Я не соглашусь. В этом случае класс SomeType будет участвовать и в других контекстах как указатель. Нет причин отказываться от оператора[].

--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
maxim1000
Дата 14.10.2005, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата
пожалуй многие согласятся с тем, что кучу перегруженных operator [] лучше заменить на пару:
operator SomeType*(void)
и
operator const SomeType*(void)

и что они будут возвращать?
для этого придется гарантировать, что все объекты контейнера идут по порядку, а это - далеко не самый частый случай...
Цитата
Ещё один плюс (на мой взгляд - наиболее значимый): в операторе [] - шаблонный класс не сможет выдать подсказку после ".", или "->" при нажатии Ctrl+Space, а в SomeType*(void) - сможет

сможет...(тестировал в Builder'е, VC под рукой нету)
Цитата
Я не очень понял что такое "вычислимые поля"

пример:
пусть мы сделали класс векторов, у которых координаты образуют арифметическую прогрессию (при создании указывается начало и шаг), при этом нам очень хотелось бы, чтобы была возможность писать cout<<v[6];
все бы хорошо, но хранить все эти значения просто расточительно
для такого вектора длиной 100 нужно будет 100 чисел, хотя можно было бы обойтись двумя (начальным элементом и шагом)
тогда можно написать такой оператор:
Код

double operator[] (int index) const
{
  return a0+index*step;
};

в этом случае ссылку возвращать попросту не на что...


--------------------
qqq
PM WWW   Вверх
GremlinProg
Дата 14.10.2005, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



Цитата
В этом случае класс SomeType будет участвовать и в других контекстах как указатель

поясни, не понял
Добавлено @ 17:46
Цитата
для этого придется гарантировать, что все объекты контейнера идут по порядку
ну и на сколько часто в коде встречается арифметическая прогрессия? Если чаще всего нужен просто УДОБНЫЙ ВЕКТОР.
Цитата
сможет...(тестировал в Builder'е, VC под рукой нету)

Вот и зря, что нету, "а какие же в билдере богатые шаблоны..." просто так, к слову.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
LPBOY
Дата 14.10.2005, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(maxim1000 @ 14.10.2005, 17:38)
пример:
пусть мы сделали класс векторов, у которых координаты образуют арифметическую прогрессию (при создании указывается начало и шаг), при этом нам очень хотелось бы, чтобы была возможность писать cout<<v[6];
все бы хорошо, но хранить все эти значения просто расточительно
для такого вектора длиной 100 нужно будет 100 чисел, хотя можно было бы обойтись двумя (начальным элементом и шагом)
тогда можно написать такой оператор:

Ну ты загнул smile Это очень нестандартный пример использования оператора []. Я имел в виду случай когда возврат по значению и по ссылке на константу по смыслу равнозначны.

Цитата(GremlinProg @ 14.10.2005, 17:41)
поясни, не понял

Во-первых ты наверное имел в виду не оператор преобразования к SomeType* , а к типу указателя на встроенный тип.

Цитата(LPBOY @ 14.10.2005, 17:29)
В этом случае класс SomeType будет участвовать и в других контекстах как указатель.

Это я имел в виду что теперь объекты SomeType можно
- разыменовывать
- складывать с целыми числами
- осуществлять неявное преобразование к bool и void*
- передавать в функцию, если на самом деле она ждет указатель и т.д.
Эти побочные эффекты явно ни к чему.

Это сообщение отредактировал(а) LPBOY - 14.10.2005, 17:55
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
GremlinProg
Дата 14.10.2005, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



Честно говоря, класс, который в операторе [] возвращает элемент, по арифметической прогрессии мне не вселил бы уверенности, т.к. его логика непонятна. Оператор [] изначально подразумевает ВЕКТОР. Не вижу логики, зачем прятать элементарную формулу в контейнере, когда можно( и нужно! ) повесить независимый класс на индекс. Повторюсь, не вижу логики, мы ведь должны облегчить читаемость кода, а не скомпоновать всё и вся


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
srd
Дата 14.10.2005, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


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

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



Цитата(LPBOY @ 15.10.2005, 01:51)
Это я имел в виду что теперь объекты SomeType можно
- разыменовывать
- складывать с целыми числами
- осуществлять неявное преобразование к bool и void*
- передавать в функцию, если на самом деле она ждет указатель и т.д.
Эти побочные эффекты явно ни к чему.

А если ещё и не увлекаться explicit конструкторами, то поведение программы может стать непредсказуемым.


--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
GremlinProg
Дата 14.10.2005, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



LPBOY
похоже, ты не понял

Код

template<typename T>
class X{
  T*  lpvector;
public:
  operator T*(){return lpvector;}
  operator const T*()const{return lpvector;}
}

пример:
Код

X<int> x;

x[2] = x[3]+x[8]

это я и имел ввиду!

здесь не создаются промежуточные экземпляры, оператор T* ведёт себя, как встроенный оператор []

Это сообщение отредактировал(а) GremlinProg - 14.10.2005, 18:00


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
maxim1000
Дата 14.10.2005, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата
ну и на сколько часто в коде встречается арифметическая прогрессия?

это был всего лишь пример на вычислимые поля
Цитата
Если чаще всего нужен просто УДОБНЫЙ ВЕКТОР

пример: частоиспользуемый страндартный контейнер map smile
или, например, динамический список с добавленной операцией доступа по номеру...
Цитата
Вот и зря, что нету, "а какие же в билдере богатые шаблоны..." просто так, к слову.

сильно подозреваю, что и в VC сможет
operator[] не очень-то от функции отличается, так что сложность определения, что выдавать при нажатии "." после значения известного типа (а тип известен) не сильно зависит от того, оператор там стоит или функция...
Добавлено @ 18:03
Цитата
Ну ты загнул  Это очень нестандартный пример использования оператора []. Я имел в виду случай когда возврат по значению и по ссылке на константу по смыслу равнозначны

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



--------------------
qqq
PM WWW   Вверх
LPBOY
Дата 14.10.2005, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(GremlinProg @ 14.10.2005, 17:58)
это я и имел ввиду!

Я понял. Я просто говорю про побочные эффекты... Чем тебе оператор [] не нравится?

Цитата(srd @ 14.10.2005, 17:56)
А если ещё и не увлекаться explicit конструкторами, то поведение программы может стать непредсказуемым.

Просто вариант с оператором преобразования не такой чистый и понятный как с оператором [].

--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
GremlinProg
Дата 14.10.2005, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



хорошо, что есть map, а то я и не знал. Вот только нотификации о изменении базы вектора я что-то там не наблюдаю. А ведь это огромный минус и как быть. Понимаешь, не всё можно найти в stl и ей подобных, иногда нужно и свои мозги включать!


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
maxim1000
Дата 14.10.2005, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата
Честно говоря, класс, который в операторе [] возвращает элемент, по арифметической прогрессии мне не вселил бы уверенности, т.к. его логика непонятна

почему непонятна?
просто этот класс представляет собой вектора с указанным ограничением
никто не запрещает хранить их в классическом виде, но "маскирование" оператора [] позволяет:
1. сократить затраты памяти
2. не заставлять пользователей класса менять свой код

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

такие вектора можно использовать при построении разреженных матриц, а это - вообще отдельная тема в численных методах...
Добавлено @ 18:08
Цитата
Вот только нотификации о изменении базы вектора я что-то там не наблюдаю

честно говоря, не понял, что имелось в виду...


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


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



Код

Просто вариант с оператором преобразования не такой чистый и понятный как с оператором [].
ты и вправду так думаешь?

class X{
public:
X(int){}
};

class Y{

public:
X operator[](unsigned id){
if(id < length){
X null;
return null
}
return lpvector[id];
}
};
допустим, Y - шаблон, а X - параметр шаблона, как в предыдущем варианте, что будет?


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
LPBOY
Дата 14.10.2005, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(GremlinProg @ 14.10.2005, 18:13)
допустим, Y - шаблон, а X - параметр шаблона, как в предыдущем варианте, что будет?

Просвети... smile
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
GremlinProg
Дата 14.10.2005, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



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

при вызове realloc(lpmem,newsize), lpmem может поменять базу, в этом случае, если в программе, где-то хранятся указатели на элементы lpmem, их нужно обновить в соответствии с новой базой, иначе при обращении к любому из таких указателей произойдёт наша любимая "Access violation"

нотификация(notification) - это шаблонный или виртуальный метод, который вызывается как раз в момет смены базы.
Добавлено @ 18:24
Цитата
Просвети...

В этом случае код просто не откомпилится, пока ты не опишешь в классе X конструктор по-молчанию. Я это к тому, что оператор TYPE [] накладывает свои ограничения на TYPE. В данном случае это очевидно.

Не всегда можно описать конструктор по-умолчанию. Если в классе есть поля типа TYPE&, то их надо в любом случае инициировать. Если в .NET можно написать так: *(TYPE*)NULL, то в C++ 6.0 этого сделать нельзя, т.к. компилятор сразу подставляет в такие места что-то вроде mov eax,[ecx], где ecx = 0 (Надеюсь идея ясна)

Это сообщение отредактировал(а) GremlinProg - 14.10.2005, 18:42


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
LPBOY
Дата 14.10.2005, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(GremlinProg @ 14.10.2005, 18:19)
В этом случае код просто не откомпилится, пока ты не опишешь в классе X конструктор по-молчанию. Я это к тому, что оператор TYPE [] накладывает свои ограничения на TYPE. В данном случае это очевидно.

Кто виноват если ты не определил конструктор по умолчанию для Х, а потом пишешь:
Цитата
X null;

Если правильно написать оператор[], то и проблем не будет.
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
srd
Дата 14.10.2005, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


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

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



Полагаю, что вместо возвращения null оператор[] должен в случае ошибки бросить исключение, либо вообще не делать никаких проверок. Семантика у него такая - не делать проверок smile)


--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
GremlinProg
Дата 14.10.2005, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



Цитата
Кто виноват если ты не определил конструктор по умолчанию для Х, а потом пишешь

Никто, просто это говорит об ограниченности класса, а если тебе нельзя по другому(см. предыд. ответ) тоты просто пишешь свой класс, вместо встроенного. Вот они, частные случаи.
Добавлено @ 18:49
Цитата
Полагаю, что вместо возвращения null оператор[] должен в случае ошибки бросить исключение, либо вообще не делать никаких проверок. Семантика у него такая - не делать проверок

Правильно, тогда чем отличается [] от TYPE smile ?
Упс, совсем из головы вылетело:

меня собственно заинтересовал момент перегрузки TYPE&operator[] и const TYPE&operator[].
Допустим есть функция:
Код

void somefunc(const TYPE&){}

и
Код

void somefunc(TYPE&){}

Если вызвать её так:
Код

somefunc(myobject[i])

то компилятор сообщит об ошибке "ambrigous access", т.е. непонятно какой оператор вызвать c const TYPE&, или TYPE&. Так вот в случае с operator TYPE*(), этой ошибки никогда не произойдёт, я специально этот момент проверял (в своё время очень нужно было).

Это сообщение отредактировал(а) GremlinProg - 14.10.2005, 19:13


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Earnest
Дата 16.10.2005, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



По-моему ты куда-то не туда загнул.
Сравнивать оператор приведения и извлечения по индексу бессмысленно, это совершенно разные операции. Оператор приведения типа многие гуру (в частности, Майерс) считают опасным и рекомендуют использовать как можно реже. Т.е. только в тех случаях, когда его семантика очевидна. Например, в классах-оболочках. А заменять ими оператор доступа к элементу контейнера - полная ересь.


--------------------
...
PM   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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