Перегрузка &

Тема в разделе "LANGS.C", создана пользователем Vilco, 10 авг 2008.

  1. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    Всплыла интересная задачка
    class CORef;
    class CORef
    {
    int data;
    public:
    CORef ()
    {
    data = 31;
    }
    CORef* operator &()
    {
    return ((CORef*) 5);
    }
    };
    А где нибудь объявлено
    CORef dummy;
    Как получить адрес dummy не прибегая к асм вставкам?
    Отсюда http://vkontakte.ru/board.php?act=topic&tid=6733893
     
  2. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    вы об этом
    Код (Text):
    1. class Foo{
    2.   public:
    3.   operator Foo*(){return this;}
    4. };
    5.  
    6. //test
    7. Foo f;
    8. Foo *pFoo = f;
    ? хотя, не совсем ясен смысл получения адреса объекта, созданного на стеке. по окончании его жизни pFoo будет указывать в космос.

    updated:
    и потом, зачем все эти сложности, если можно:
    Код (Text):
    1. Foo *pFoo = &f;
     
  3. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Ну можно так )).
    Код (Text):
    1. CORef *pDummy = (CORef*)&dummy.data;
     
  4. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    Ага, а если первый член класса private (даже отредактировал первый пост=)? Нужен то универсальный метод.
    Да не важен практический смысл, считайте это.. теоретической задачкой.
     
  5. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    Vilco
    так вам нужен адрес поля объекта или же адрес самого объекта? если второе, то неясно, чем не устраивает предложенный вариант выше.
     
  6. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    Нельзя так. Кроме того, что С-cast применённые к объекту - это UB, так ещё и внутренние данные сюда замешивать :) Не учи людей плохому :)

    В этом случае вот Foo *pFoo = &f; не работает?
     
  7. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    Не понял вопроса. Если f это наш объект, то pFoo будет равно 5, но никак не реальному адресу.
     
  8. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Ну тогда что-то вроде этого. ))
    Код (Text):
    1. CORef dummy;
    2. CORef *pDummy = 0;
    3. pDummy = (CORef*)(&pDummy+3);
    W4FhLF
    Чего? Я применил каст в указателю. И при чём здесь С-cast?
     
  9. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    Тогда уж лучше
    CORef dum;
    CORef* pdum;
    dd = (CORef*)((unsigned int)&pdum + sizeof(CORef));
    Но некрасиво както, чтож я каждый раз вручную смещение буду считать? Можно ли путем каких-либо хитрых манипуляций с идентификатором dum это сделать?
     
  10. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    Vilco
    ты бы объяснил таки, чтО тебе нужно. повторюсь:
     
  11. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    Мне нужен адрес объекта, чтобы я мог к его методам и данным иметь доступ через указатель
     
  12. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    На самом деле можно сделать метод GetPtr. Но я думал что это задачка для ума. -)

    Код (Text):
    1. CORef dum;
    2. CORef* pdum;
    3. dd = (CORef*)((unsigned int)&pdum + sizeof(CORef));
    Боюсь что здесь всё несколько сложнее, ибо во первых стек растёт с сверху вниз, и ещё тут надо учитывать как это делает конкретный компилятор и как происходит выравнивание. )
     
  13. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    Вот этот изврат работает=)

    pdum = (CORef*)&((int&)dum);
     
  14. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    Vilco
    а тебе принципиально нужно, чтобы член int data был размещен в private-секции класса Foo и чтобы обойтись без геттера? :))
    ежели хочется таких извращений, то придется воспользоваться reinterpret_cast:
    Код (Text):
    1. class Foo{
    2.    int _data;
    3. public:
    4.    Foo(int data):_data(data){}
    5.    void printData() const{ printf("_data=%d\n", _data); }
    6. };
    7.  
    8. //
    9. Foo f(666);          
    10. Foo *pFoo = &f;
    11.    
    12. int data_offset = 0;
    13. int& i = *reinterpret_cast<int*>(reinterpret_cast<size_t>(pFoo) + data_offset);
    14. i = 777;
    15. pFoo->printData(); // 777
    про портируемость и надежность этого хака я промолчу.
    а вообще, если бы у нас был не класс а, скажем, структура, то можно было бы смещение _data вычислить через макрос offsetof, определенный в хидере <cstddef>
     
  15. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Vilco
    Код (Text):
    1. CORef *pDummy = (CORef *)&(char&)dummy;
     
  16. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    бррр..
    ежели не требуется получить доступ к приватным членам, то нафига городить огород?
    Код (Text):
    1. Foo f;
    2. Foo *pFoo = &f;
    получили адрес объекта f, созданного на стеке. какая нам разница, какова его внутренняя структура, если более от нас ничего не требуется? вообще, не топик, а сумбур какой-то.
     
  17. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    если этот изврат по изменению приватных данных класса извне вам нужен, то можно еще поглядеть на неск. реализаций:
    http://cppforeach.wordpress.com/2008/05/19/around_access_modifiers/
    ps: на самом деле имхо это нафик не надо и представляет из себя сугубо имхо эстетический интерес. на практике за такое надо бить линейкой по рукам.
     
  18. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    Так нельзя сделать. Что тут непонятного? &f вернет не адрес, а значение (Foo*)5.
     
  19. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Vilco
    Код (Text):
    1. pdum = (CORef*)&((int&)dum);
    Прикольно, о таком изврате даже не знал. ))
     
  20. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    Vilco
    теперь ясно. я не знал что вам нужно чтобы в классе обязательно присутствовал
    Код (Text):
    1. CORef* operator &()
    2.     {
    3.     return ((CORef*) 5);
    4.     }
    это называется -- мы успешно решаем проблемы, которые сами же и придумываем :)
    не в обиду:)