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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перегрузка =, ->, (), [], Почему только методами? 
:(
    Опции темы
0x07L
Дата 15.6.2006, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



сабж 
PM MAIL   Вверх
skyboy
Дата 15.6.2006, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


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

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



а функциями разве нельзя? или как надо? 
PM MAIL   Вверх
Earnest
Дата 15.6.2006, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



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

Добавлено @ 20:12 
Пыталась представить себе глобальную перегрузку оператора, скажем ()... 

Стандартный оператор () применим только к функциям. Значит, перегрузим мы его глобально, и вместо вызова ожидаемой функции с некоторыми типами аргументов будет вызываться... что? Другая функция? Очень полезно. Главное, наглядно.

Аналогично с другими операциями: [] в стандартном виде применим только к указателям-массивам и только с целыми индексами. Перегрузили. С индексами типа complex. А что, нельзя? Какой смысл будет иметь выражение pA[c], где pA указатель, а с - complex? Ммм... наверное индексация в двумерном массиве, не иначе...

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


--------------------
...
PM   Вверх
MAKCim
Дата 15.6.2006, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



потому как это может нарушить семантику использования языковых средств
честно говоря даже не представляю, зачем это вообще надо (кроме разве что operator=) 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
0x07L
Дата 15.6.2006, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Зачем запрещать, если можно разрешить. Неужели найдутся программисты, которые захотят использовать индексы типа complex? А дополнительные возможности (даже такие сомнительные) тоже могут кому-нибудь пригодиться IMHO. 
PM MAIL   Вверх
DeadSoul
Дата 15.6.2006, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(0x07L @  15.6.2006,  21:31 Найти цитируемый пост)
Неужели найдутся программисты, которые захотят использовать индексы типа complex? 

std::map. 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
MAKCim
Дата 15.6.2006, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата

Зачем запрещать, если можно разрешить. Неужели найдутся программисты, которые захотят использовать индексы типа complex? А дополнительные возможности (даже такие сомнительные) тоже могут кому-нибудь пригодиться IMHO. 

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

p.s приведи хоть один пример, где перегрузка глобальных [], (), -> может пригодится? 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
0x07L
Дата 15.6.2006, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(MAKCim @  15.6.2006,  21:49 Найти цитируемый пост)
если такой логике следовать, то в язык можно много чего еще ввести

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

Цитата(MAKCim @  15.6.2006,  21:49 Найти цитируемый пост)
приведи хоть один пример, где перегрузка глобальных [], (), -> может пригодится? 

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

PS Приведите, пожалуйста, пример, когда дружественной функцией перегружается оператор , (запятая). Вроде, ничуть не лучше, чем [ ]. Мне чего-то это начинает казаться бессмысленным.

Цитата(DeadSoul @  15.6.2006,  21:46 Найти цитируемый пост)
Цитата(0x07L @  15.6.2006,  21:31 )    
Неужели найдутся программисты, которые захотят использовать индексы типа complex?  

std::map. 

Это другое дело smile

Цитата(Earnest @  15.6.2006,  20:03 Найти цитируемый пост)
 Тихо приходим к выводу, что смысл этих операций должен зависеть от типа левого операнда. А раз так, то имеет смысл выразить сию идею явно: запретить глобальную перегрузку. 

А если левый операнд - член какого-нибудь библиотечного класса, к которому мы не можем добавить метод. Тогда, по аналогии с cin/cout мы можем только использовать дружественную функцию.

То есть нам, к примеру, нужно реализовать оператор вида a[ b ], где а - объект библиотечного класса, b - объект класса, который проетируем мы. Мы не можем добавить operator[] к методам библиотечного класса. Мы не имеем возможности реализовать такое методом нашего класса, поскольку ему через указатель this передается левый операнд. Остается только добавить к нашему классу дружественную функцию operator[] (const A & a, const B & b) или что-нибудь подобное.

Цитата(MAKCim @  15.6.2006,  20:59 Найти цитируемый пост)
кроме разве что operator= 

А чем operator= лучше operator[] или ...-> или ...()? 
   

Это сообщение отредактировал(а) 0x07L - 15.6.2006, 22:24
PM MAIL   Вверх
skyboy
Дата 15.6.2006, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


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

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



Цитата(0x07L @  15.6.2006,  22:09 Найти цитируемый пост)
А чем operator= лучше operator[] или ...-> или ...()? 

я бы добавил ещё сравнение ==
Почему только это? А потому что копирование объектов ("=") может сопровождаться кучей условий и вызовом конструкторов, который не совершает "стандартная" операция копирования объектов. Почему сравнение? А чтоб упростить сравнение сложных типов - тех же списков или структур. 
PM MAIL   Вверх
Earnest
Дата 16.6.2006, 07:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(0x07L @  15.6.2006,  23:09 Найти цитируемый пост)
А если левый операнд - член какого-нибудь библиотечного класса, к которому мы не можем добавить метод. 

Есть такое понятие - адаптер. Пиши свой класс, и делай с ним, что хочешь.

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

Цитата(skyboy @  15.6.2006,  23:35 Найти цитируемый пост)
я бы добавил ещё сравнение ==

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

 


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


неОпытный
****


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

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



Earnest, знач, переопределять только в front-end модуле,  только в котором мы это сравнение и будем использовать и который не будет подключаться к другим модулям(в смысле, по задумке ЕГО не будут подключать) 
PM MAIL   Вверх
Earnest
Дата 16.6.2006, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Это из серии "благими намерениями". 

Исходный код имеет тенденцию жить своей жизнью. Сначала ты переопределяешь глобальный оператор (скажем сравнения объектов A) в cpp-файле, и счастлив - быстро, удобно, работает. Потом постепенно разрастается  до неприличных размеров, и надо его делить. А как же наш специальный оператор? Он уже должен использоваться в 2 файлах. Дублируем код? Выносим в заголовок? И то, и другое одинаково плохо. 
Причем, заметь, это может сделать совсем другой программист (а не автор первой версии кода). Или автор, но через несколько лет.

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

А искать такие ошибки - сплошная радость. Гораздо проще написать класс - обертку, подогнав под свои нужды. Это уж точно никогда никому не повредит. 


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


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата

Приведите, пожалуйста, пример, когда дружественной функцией перегружается оператор , (запятая). Вроде, ничуть не лучше, чем [ ]. Мне чего-то это начинает казаться бессмысленным.

OK
Код

#include <vector>
#include <iostream>

class container
{
private:
    std::vector<int> array_;
private:
    class reader
    {
    private:
        container& reference_;
    public:
        reader(container& ref, int obj)
            : reference_(ref) { reference_.array_.push_back(obj); }

        friend reader operator,(reader rd, int obj)
        {
            return reader(rd.reference_,obj);
        }
    };

    friend class reader;
public:
    reader operator<<(int obj)
    {
        return reader(*this,obj);
    }

    void print(std::ostream& stream)
    {
        for (std::vector<int>::iterator i=array_.begin();
                i!=array_.end(); ++i) stream<<*i;
    }
};

int main()
{
    container p;
    p<<1,2,3,4;
    p.print(std::cout);
    return 0;
}
 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

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


неОпытный
****


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

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



Earnest, полностью согласен. И рад, что в жизни не переопределял операторы, ибо с С++ почти не работаю  smile  
PM MAIL   Вверх
0x07L
Дата 16.6.2006, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



2_MAKCim

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

2_Earnest

Дельное замечание.

---------------------------

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

А вот относительно оператора присваивания меня переубедить не смогли.
Хотя...

Как известно, operator=, если не переопределен, конструируется (если можно так выразиться) компилятором и осуществляет побайтовое копирование объекта. Переопределяют operator= прежде всего для того, чтобы обеспечить правильную работу указателей-членов класса.  А тот, кто переопределяет operator= стандартного класса дружественной функцией для поддержки возможности присваивания объекту такого класса объекта нашего класса, не имеет доступа к этим указателям. Между тем смысл оператора присваивания в том, чтобы полностью менять левый операнд (а не прибавлять к какому-нибудь элементу объекта какое-либо значение, не делить, не умножать, не возводить в степень, ... не получать доступ к какому-либо элементу), что предполагает изменение этих указателей. Получается, вообще говоря, хрень и никому эта хрень, естественно, не нужна. Вопрос по operator= решен.

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

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

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

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

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


 




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


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

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