Как получить указатель на переменную 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
материалам из класса.
Реализации таблиц виртуальных функций является компилятор иждивенца. Существует даже требование использовать таблицы виртуальных функций. –
Обновите свой вопрос, чтобы показать, как вы будете использовать указатель на таблицу виртуальных функций (зачем вам нужно * указатель на таблицу функций?). –
Этот вопрос трудно понять, потому что неясно, в каком контексте вы его спрашиваете. Вы спрашиваете, как изменить код? Как добавить существующий код без изменения этого кода? Как это сделать с помощью отладчика? Это поможет очень многое понять, какую проблему вы пытаетесь решить с этим, поскольку это сделает контекст понятным. –