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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Хитрый доступ к private полям/методам класса 
:(
    Опции темы
Aqs
Дата 12.5.2010, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Здравствуйте!
Вопрос таков - как получить из внешней функции доступ к private полям и методам класса, при этом ничего в самом классе не изменяя ? (вариант объявить методы и поля как public тоже не подходит) 

Например, из main, модифицировать и вывести на экран поле a, и вызвать метод c, определенные в следующем тривиальном классе:
Код

class A {
      int a;
      int b () {
          return 345;
      }
}; 


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


Это сообщение отредактировал(а) Aqs - 12.5.2010, 19:09
PM MAIL   Вверх
azesmcar
Дата 12.5.2010, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



через грязные хаки
Код

#define private public
#define class struct

class A {
      int a;
      int b () {
          return 345;
      }
};

но это непереносимо, стандарт не позволяет определять макросы с ключевыми словами.
Цитата

A translation unit that includes a header shall not contain any macros that define names declared or defined
in that header. Nor shall such a translation unit define macros for names lexically identical to keywords.


Добавлено через 1 минуту и 9 секунд
еще для доступа к переменным можно подменить класс идентичным через reinterpret_cast..

но зачем это надо?
PM   Вверх
toxx
Дата 12.5.2010, 20:38 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



azesmcar
сорри за оффтоп , но напоминает идусский код...  smile 
Код

#define true false


Это сообщение отредактировал(а) toxx - 12.5.2010, 20:38
PM MAIL   Вверх
azesmcar
Дата 12.5.2010, 20:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(toxx @  12.5.2010,  20:38 Найти цитируемый пост)
сорри за оффтоп , но напоминает идусский код...  smile 

так и есть smile только на логику выполнения не влияет.
вот это кстати получше
Код

#define sizeof(X) rand()


Это сообщение отредактировал(а) azesmcar - 12.5.2010, 20:42
PM   Вверх
Aqs
Дата 12.5.2010, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(azesmcar @ 12.5.2010,  20:28)
но зачем это надо?

Задание такое получил, в университете... smile
PM MAIL   Вверх
kemiisto
Дата 12.5.2010, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



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

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



Цитата(Aqs @  12.5.2010,  21:45 Найти цитируемый пост)
Задание такое получил, в университете...

Да, всё правильно написали. smile Такие университеты только с маленькой буквый и писать. А по-хорошему...


--------------------
PM MAIL WWW GTalk Jabber   Вверх
azesmcar
Дата 12.5.2010, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Не устану повторять, такие вопросы лучше задавать в google-е...он все знает
user posted image

Это сообщение отредактировал(а) azesmcar - 12.5.2010, 20:51
PM   Вверх
Aqs
Дата 12.5.2010, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Если бы было так легко найти, я бы уже давно нашел smile Перерыл за сегодня не один десяток форумов и сайтов - именно такая задача не встречается нигде.
Понадеялся что тут найдутся знающие люди, которые помогут.
Кстати, вариант с грязными хаками неподходит - нужно что-то более "легальное" smile Да и препод намекнул, что тут до полей и методов нужно добираться именно через адрес.
PM MAIL   Вверх
azesmcar
Дата 12.5.2010, 21:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(Aqs @  12.5.2010,  20:57 Найти цитируемый пост)
Если бы было так легко найти, я бы уже давно нашел smile Перерыл за сегодня не один десяток форумов и сайтов - именно такая задача не встречается нигде.

Я показал что надо искать smile 
хотя если серьезно то тем в интернете дофига
http://www.google.mu/search?hl=en&clie...q=&gs_rfai=

Цитата(Aqs @  12.5.2010,  20:57 Найти цитируемый пост)
Кстати, вариант с грязными хаками неподходит - нужно что-то более "легальное" smile Да и препод намекнул, что тут до полей и методов нужно добираться именно через адрес. 

легальный способ friend-ы, еще можно через шаблоны, игры с адресами - грязный хак.
Код

A t;
std::cout << *((int*)&t) << std::endl;

до переменный можно добраться так, до функции насколько я помню никак не добраться без макросов.
PM   Вверх
Леопольд
Дата 12.5.2010, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Aqs @  12.5.2010,  20:45 Найти цитируемый пост)
Задание такое получил
Препод, видимо, С++ по Подбельски учил... smile В общем, учит он абсолютно ненужной фигне. Бредятина. Лучше бы задал реализовать какой-нибудь паттерн проектирования. Хотя, он наверное и слова такого не слышвл...

Это сообщение отредактировал(а) Леопольд - 12.5.2010, 22:07


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Alek86
Дата 12.5.2010, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



есть только один нормальный способ это сделать, но только если у класса есть хоть одна неприватная шаблонная функция-член
описан у Саттера, причем очень красиво

но уверен, препод его в виду не имел


--------------------
user posted image    user posted image
PM MAIL   Вверх
Леопольд
Дата 12.5.2010, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Alek86 @  12.5.2010,  22:05 Найти цитируемый пост)
но уверен, препод его в виду не имел
Цитата(Aqs @  12.5.2010,  19:09 Найти цитируемый пост)
при этом ничего в самом классе не изменяя


Добавлено через 3 минуты и 29 секунд
Цитата(azesmcar @  12.5.2010,  21:06 Найти цитируемый пост)
до переменный можно добраться так
А если с множественным наследованием или виртуальными функциями? Вроде бы, если это не POD, то behaviour is undefined.


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
azesmcar
Дата 12.5.2010, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(Леопольд @  12.5.2010,  22:08 Найти цитируемый пост)
А если с множественным наследованием или виртуальными функциями? Вроде бы, если это не POD, то behaviour is undefined. 

Я уже написал что это грязный и непереносимый хак, который к тому же касался конкретно описанного класса.

Это сообщение отредактировал(а) azesmcar - 12.5.2010, 22:22
PM   Вверх
Леопольд
Дата 12.5.2010, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



azesmcar, я понимаю что ты знал почему это хак.  smile Я топикстартера на мысль навёл.


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Леопольд
Дата 12.5.2010, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Вот мой вариант "бреда"  smile Но, пришлось немного поменять исходный класс.

http://codepad.org/uRXBy0SZ 
Код
#include <iostream>

class A {
      int a;
      virtual int b () {
          return a;
      }
};
struct B{
      int a;
      virtual int b ();
};

int main(){
    A obj;
    B* ptr = static_cast<B*>(static_cast<void*>((&obj)));
    ptr->a = 123;
    std::cout<<ptr->b()<<std::endl;
    return 0;
}


Твоему чокнутому профессору должно понравиться, ведь ещё и на vtbl завязано.  smile 
Разберись что такое "виртуальная таблица функций" и по ушам ему этим проедь. Глядишь, зачтёт. Ты главное напирай на то, что это зачётно! smile

З.Ы. Это пример как нельзя кодить.

Это сообщение отредактировал(а) Леопольд - 12.5.2010, 23:03


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Alek86
Дата 12.5.2010, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Леопольд @  12.5.2010,  22:08 Найти цитируемый пост)
Цитата(Alek86 @  12.5.2010,  22:05 )но уверен, препод его в виду не имелЦитата(Aqs @  12.5.2010,  19:09 )при этом ничего в самом классе не изменяя

ну и чего в классе в случае шаблона меняется? специализации могут быть хоть в другом cpp


--------------------
user posted image    user posted image
PM MAIL   Вверх
Леопольд
Дата 12.5.2010, 23:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Alek86 @  12.5.2010,  22:57 Найти цитируемый пост)

ну и чего в классе в случае шаблона меняется?
Цитата(Alek86 @  12.5.2010,  22:05 Найти цитируемый пост)
но только если у класса есть хоть одна неприватная шаблонная функция-член
Ты меня, видимо, неправильно понял. Нет такой функции в исходном классе (см. первый пост).


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Alek86
Дата 12.5.2010, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Леопольд @  12.5.2010,  22:48 Найти цитируемый пост)
Вот мой вариант "бреда"   Но, пришлось немного поменять исходный класс.

а зачем виртуальные функции?


--------------------
user posted image    user posted image
PM MAIL   Вверх
Леопольд
Дата 12.5.2010, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Alek86 @  12.5.2010,  23:02 Найти цитируемый пост)

а зачем виртуальные функции? 
Обрати внимание на то, что функция b реализована только в A классе. ptr->b() вызывается через vtbl класса A. Я же говорю, зачётно. smile

Это сообщение отредактировал(а) Леопольд - 12.5.2010, 23:12


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Aqs
Дата 12.5.2010, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо за идею, но... Исходный класс изменять нельзя вообще никак, в этом-то и вся соль - у меня тоже была мысль что-то замутить с виртуальными функциями, но без переобъявления метода b как виртуального и в классе А, ничего не выйдет. А делать этого нельзя, по условию. Да и с виртуальными функциями уже по курсу имели тесное общение - мозги ему запудрить неполучится  smile 

С полями вроде разобрался... Идея похожа на Вашу (используется так же вспомогательный класс) :
Код

#include <iostream>

class A{
    int a;
    int b() { return 123; }
public:
    A() : a(10) {}
};

struct Clone { int a; };

int main( ){
    A a;
    void *pv = &a; 
    Clone *pc = (Clone*)pv; 
    std::cout<<pc->a<<std::endl; 
}


А вот с методами по-прежнему непонятно что делать.

Это сообщение отредактировал(а) Aqs - 12.5.2010, 23:15
PM MAIL   Вверх
Леопольд
Дата 12.5.2010, 23:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Aqs @  12.5.2010,  23:13 Найти цитируемый пост)
А вот с методами по-прежнему непонятно что делать. 
Цитата(azesmcar @  12.5.2010,  21:06 Найти цитируемый пост)

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

Aqs, я ему верю больше чем твоему преподу - маньяку.  smile 


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Aqs
Дата 12.5.2010, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Леопольд @  12.5.2010,  23:19 Найти цитируемый пост)
Aqs, я ему верю больше чем твоему преподу - маньяку.  smile  

Да, я тоже с каждым часом начинаю всё больше сомневаться в реализуемости этого... smile
Хотя конечно может решение и есть, но видимо только преподы-маньяки знают его smile 
PM MAIL   Вверх
Леопольд
Дата 12.5.2010, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



http://codepad.org/6Ll4wy13
Нельзя взять адрес приватной функции.

Это сообщение отредактировал(а) Леопольд - 12.5.2010, 23:26


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 13.5.2010, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Aqs @  12.5.2010,  22:24 Найти цитируемый пост)
Да, я тоже с каждым часом начинаю всё больше сомневаться в реализуемости этого... 

попробую развеять сомнения smile

Код

// a.h 
...
class A {
    int a;
    int b ();
};

Код

//a.cpp
#include "a.h"
int A::b () { return 345; }

Код

//main.cpp

class A; // forward declaration

void hack_init  (A&);   
void hack_print (A&); // прототипы хак-функций (можно вынести в а_hack.h)

#include <a.h> // включаем оригинал после прототипов

int main() 
{
    A a;
    hack_init  (a);
    hack_print (a);    //  применяем хак-функции
     
    
    return 0;
}

Код

// a_hack.cpp
#include <iostream>

// хак-копия класса 
// должна иметь то же самое имя,  но может быть объявлена как структура,
// порядок дата-членов должен быть соблюден
// приват-функция оригинала не должна быть инлайн.. (определена внутри класса), иначе ее тоже нужно определять в hack-копии
struct A {

    int a;
    int b ();
};  

void hack_init (A& obj)
{
    obj.a = 7;
}


void hack_print (A& obj)
{
    std::cout << obj.a << " " << obj.b();
}


надеюсь очепяток не допустил smile


Это сообщение отредактировал(а) mes - 13.5.2010, 12:30


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


Новичок



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

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



mes, спасибо! Действительно, всё отлично работает smile
Только вот осталось непонятным, почему обязательно нужно объявлять b() вне класса A ?
Если b() будет объявлена внутри, то получается нужно в структуре продублировать код функции? 


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


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


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

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



Цитата(Aqs @  13.5.2010,  13:05 Найти цитируемый пост)
Если b() будет объявлена внутри, то получается нужно в структуре продублировать код функции? 

ага 

Цитата(mes @  13.5.2010,  11:15 Найти цитируемый пост)
приват-функция оригинала не должна быть инлайн.. (определена внутри класса), иначе ее тоже нужно определять в hack-копии


или можно поступить проще, воспользоваться дефайнами, как предлaгал azesmzar, 
но применить его только в a_hack.cpp файле, так сказать компромисс - весь хак будет собран в одном месте и никого другого не зацепит.. smile

Код

// a_hack.cpp
#include <iostream>

#define class struct
#define private public
#define protected public

#include "a.h"
  
void hack_init (A& obj)
...



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


Эксперт
***


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

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



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


--------------------
user posted image    user posted image
PM MAIL   Вверх
mes
Дата 13.5.2010, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Alek86 @  13.5.2010,  15:16 Найти цитируемый пост)
хотя четких доказательств нету 

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


Это сообщение отредактировал(а) mes - 13.5.2010, 18:06


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


Эксперт
***


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

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



Цитата(mes @  13.5.2010,  18:05 Найти цитируемый пост)
достаточно того, что у нас получаются два разных описания класса

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


--------------------
user posted image    user posted image
PM MAIL   Вверх
mes
Дата 13.5.2010, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Alek86 @  13.5.2010,  20:50 Найти цитируемый пост)
вот я и не знаю, запрещает ли это стандарт явно
шаблонные методы тоже могут привести к разным описаниям... 

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

В стандарте (раздел ODR) накладывается ряд ограничений, после которых обе копии считаются идентичными, но рассматривается ли там наша ситуация, я так и не понял smile


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


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

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