2016-06-01 3 views
1

У меня есть класс, таких какполучение указателя виртуальной таблицы C++

class Stuff 
{ 
private: 
int x; 
virtual int buisness() 
{ 
    return 42; 
} 
public: 
Stuff(){ 
    x = 5; 
} 

Данный указатель на экземпляр этого класса

Stuff stuff; 
void* thing = &stuff; 

Как бы я получить указатель на переменную х и указатель к таблице виртуальных функций этого класса, используя только указатель «вещь»?

Редактировать: чтобы разъяснить, что это был вызов, посланный мне, и я был уверен, что это не трюк.

+6

Реализации таблиц виртуальных функций является компилятор иждивенца. Существует даже требование использовать таблицы виртуальных функций. –

+7

Обновите свой вопрос, чтобы показать, как вы будете использовать указатель на таблицу виртуальных функций (зачем вам нужно * указатель на таблицу функций?). –

+2

Этот вопрос трудно понять, потому что неясно, в каком контексте вы его спрашиваете. Вы спрашиваете, как изменить код? Как добавить существующий код без изменения этого кода? Как это сделать с помощью отладчика? Это поможет очень многое понять, какую проблему вы пытаетесь решить с этим, поскольку это сделает контекст понятным. –

ответ

8

Как получить указатель на переменную x и указатель на таблицу виртуальных функций этого класса, используя только указатель «вещь»?

Вы не можете без литья thing обратно к первоначальному типу:

Stuff* stuff2 = reinterpret_cast<Stuff*>(thing); 

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

Фактический макет определяется реализацией и пытается использовать смещения от вещь и предположения о размерах не соответствуют стандартным механизмам C++.


Это звучит, как вы хотите, чтобы обойти private политику доступа члена класса с известной компоновки этих членов. Вот крайне грязный хак:
Disclamer: Не делайте этого в производственном коде !!

#include <iostream> 

class Stuff { 
private: 
    int x; 
    virtual int business() { 
     std::cout << "Have that 42 ... " << std::endl; 
     return 42; 
    } 
public: 
    Stuff() { 
     x = 5; 
    } 
}; 

struct StuffProxy { 
    // Make the layout public: 
    int x; 
    virtual int business(); 
}; 

int main() { 
    Stuff stuff; 
    void* thing = &stuff; 

    // Here's the nasty stuff 
    StuffProxy* stuffProxy = reinterpret_cast<StuffProxy*>(thing); 
    int* addrX = &(stuffProxy->x); // Get the address of x 
    std::cout << "x = " << *addrX << std::endl; 

    typedef int (Stuff::*StuffFunc)(); 
    StuffFunc stuffFunc = (StuffFunc)(&StuffProxy::business); 
    std::cout << "business() = " << (stuff.*stuffFunc)() << std::endl; 
} 

Выход:

x = 5 
Have that 42 ... 
business() = 42 

Live Demo

Вышеуказанные работы, потому что это гарантирует, что class и struct будет иметь тот же формат в C++ реализации компиляторов, с той лишь разницей, видимости членов во время компиляции.

Итак, если у вас есть макет класса (например, из заголовка), и вы готовы поддерживать его в течение всего срока службы вашего проекта, вы можете предоставить такой прокси-сервер, как указано выше, для доступа к private материалам из класса.

2

Чтобы получить доступ к private члену x:

1) Объявляют функцию, которая должна получить доступ к x, как друг класса.

2) Изменить доступ к public.

3) Написать публичный геттер или setter функции.

4) Измените свой дизайн; Другие классы не должны знать о переменных-членах.

+0

Вы можете обойти все эти правила (не то, что я рекомендую), если вы не спрячете все, кроме «pimpl» (и лучше всего использовать неназванные пространства имен для реальной реализации). –

0

Это может быть зависимо от компилятора. Я только что сделал массив символов из указателя «вещи»

char *array; 
array = (char*)thing; 

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

int x = array[8]; 
Смежные вопросы