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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> неявное преобразование типов 
:(
    Опции темы
zss
Дата 6.6.2006, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



есть классы (могут быть ошибки - писал здесь, но думаю смысл понятен)
Код

class Item
{
...
int size () const;
Item& operator = (int rhs);
...
}

class Items{
    Item item_;
    operator const Item& () const {return item_;}
    operator Item& () {return item_;}
}


но я не могу использовать оператор
Код

Items items;
int k = items.size();
items = 100;


почему ? ведь оператор определен
Код

    operator Item& () {return item_;}
    operator const Item& () const {return item_;}
 
PM MAIL ICQ   Вверх
LPBOY
Дата 6.6.2006, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(zss @  6.6.2006,  14:07 Найти цитируемый пост)
items = 100;

В таких случаях, для операторов-мемберов, никогда не происходят преобразования. Если у Items нет подходящего оператора=, то просто выдается ошибка. Преобразование произошло бы, если бы мог существовать глобальный оператор Item& operator=(Item& lhs, int rhs){...}. smile 
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
zss
Дата 6.6.2006, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(LPBOY @  6.6.2006,  14:38 Найти цитируемый пост)
В таких случаях, для операторов-мемберов, никогда не происходят преобразования. Если у Items нет подходящего оператора=, то просто выдается ошибка.


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


Цитата(LPBOY @  6.6.2006,  14:38 Найти цитируемый пост)
Преобразование произошло бы, если бы мог существовать глобальный оператор Item& operator=(Item& lhs, int rhs){...}


этого тоже не очень хочется делать

Может есть способ проще - что-нибудь с proxy-классами. Или как еще заставить неявно преобразовать типы smile
 
PM MAIL ICQ   Вверх
MAKCim
Дата 6.6.2006, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата

int k = items.size();

в C++ нет перегрузки operator.()

Добавлено @ 16:29 
Цитата

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

попробуй через operator->()
Код

class Item
{
...
int size () const;
Item& operator = (int rhs);
...
};

class Items{
    Item* item_;
public:
    Items(): item_(new Item) {}

    Item* operator->() {return item_;}
    const Item* operator->() const {return item_;}
};

но тогда станут доступны через operator->() все public методы Item-а 


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

PM MAIL   Вверх
MAKCim
Дата 6.6.2006, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Код

class Item
{
...
int size () const;
Item& operator = (int rhs);
...
};
class Items{
    Item item_;
private:
    class proxy: public Item
    {
    private:
         Item& obj;
    private:
         void set_ref() {obj=*this;}
         void set_obj() {static_cast<Item&>(*this)=obj;}

        // Тут using-ом можно запрещать методы Item-а
    public:
         proxy(Item& p_obj): obj(p_obj) {set_obj();}
         ~proxy() {set_ref();}
    };
public:
    proxy get() {return proxy(item_);}
};
  

Это сообщение отредактировал(а) MAKCim - 6.6.2006, 16:50


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

PM MAIL   Вверх
Earnest
Дата 6.6.2006, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



MAKCim, мне кажется, первый вариант лучше (только там никто не заставлет указатель хранить, можно и прямо объект). Применение прокси вроде ничем не оправд
ано.
Цитата(MAKCim @  6.6.2006,  17:22 Найти цитируемый пост)
но тогда станут доступны через operator->() все public методы Item-а  

Так этого zss и добивается - получить доступ к открытым членам Item.
Есть еще вариант с оператором () (если указательная семантика не нравится).

Код

class Items{
    Item item_;
public:
    // ...
    Item& operator()() {return item_;}
    const Item& operator()() const {return item_;}
};

Items items;
int k = items().size();
 


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


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


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

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



Цитата

только там никто не заставлет указатель хранить, можно и прямо объект

можно  smile 
Цитата

Применение прокси вроде ничем не оправд
ано.

Код

...
Items items;
delete items.operator->();

 smile 
кроме того есть возможность ограничить использование некоторых методов Item-а (хотя может это и не нужно) 


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

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


Эксперт
****


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

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



Цитата(MAKCim @  6.6.2006,  20:39 Найти цитируемый пост)
delete items.operator->();

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

 


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


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


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

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



Цитата

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

Это да
просто в принципе такое можно сделать 


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

PM MAIL   Вверх
zss
Дата 7.6.2006, 08:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



что-то не очень помагает

если быть точным, то весь код примерно такой
Код

class Item
{
    ...
    int size(void) const;
    Item& operator += (size_t rhs);
    ...
}

typedef std::map<int, Item> pack_map;
typedef pack_map::const_iterator it_pack;

class Some
{
private :
    pack_map items_;

    class ItemProxy {
    private :
        friend class Some;
        pack_map& map_;

        explicit ItemProxy (pack_map& map) : map_ (map) {;}
        ItemProxy& operator = (const ItemProxy&);
        ItemProxy& operator += (const ItemProxy& rhs);

        class Proxy {
        private :
            friend class ItemProxy;
            pack_map& map_;
            int key_;

            Proxy (pack_map& map, int key)
                : map_(map), key_(key){;}
            Proxy& operator = (const Proxy&);

        public :
            Item& operator () (void);
            const Item& operator () (void) const;

        };

    public :
        Proxy operator [] (int key);
        const Proxy operator [] (int key) const;
    };

public :

    ItemProxy items;
}


и тогда
Код

    Some some;
    some.items[0].size(); // ошибка
    some.items[0] += 10;  // ошибка
 
PM MAIL ICQ   Вверх
Earnest
Дата 7.6.2006, 08:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Опять на те же грабли наступаешь... Оператор преобразования типа здесь не поможет... И вообще, не стоит им злоупотреблять: в данном контексте его применение неоправданно.
Короче, прямо по Items (без скобок (), -> или функции get(), как в примере MAKCima, получить доступ к элементам Item не получится. Потому что компилятор не будет применять преобразование типа к левому операнду "[]",".", etc. 


--------------------
...
PM   Вверх
zss
Дата 7.6.2006, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Earnest, блин...

но ведь делают как-то. Например многие библиотеки в Builder именно так и работают

Значит можно извратиться smile

Добавлено @ 08:44 
Цитата(MAKCim @  6.6.2006,  16:22 Найти цитируемый пост)
попробуй через operator->()


не хотелось бы так делать - не совсем понятно (интуитивно) для пользователей 
PM MAIL ICQ   Вверх
MAKCim
Дата 7.6.2006, 09:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата

не хотелось бы так делать - не совсем понятно (интуитивно) для пользователей  

а это интуитивно понятно что-ли?
Цитата

int k = items.size();

непонятно что за size() есть у Items
Цитата

Значит можно извратиться 

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


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

PM MAIL   Вверх
zss
Дата 7.6.2006, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(MAKCim @  7.6.2006,  09:13 Найти цитируемый пост)
непонятно что за size() есть у Items


в последнем примере есть операторы [] - поэтому сразу понятно, что это массивы 
PM MAIL ICQ   Вверх
Earnest
Дата 7.6.2006, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(zss @  7.6.2006,  09:42 Найти цитируемый пост)
Например многие библиотеки в Builder именно так и работают

Скорее всего это ты что-то не так понял: или наследование, 
или переопределение необходимых операторов\функций делегированием ([], size(), etc). 


--------------------
...
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1555 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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