Итак, я повеселился и немного манипулировал кодом. Это тоже эмпирический ответ. При таком способе действий существует множество подводных камней, которые рискуют испортить стек, поэтому я немного изменил код, чтобы сделать его таким, чтобы не допускать повреждения стека, а показывать, как это происходит.
#include <iostream>
class IService {
public:
int x;
};
class X_Service {
public:
int x;
void service1() {
this->x = 65;
std::cout << this->x << std::endl;
}
};
int main() {
IService service;
auto func = reinterpret_cast<void (IService::*)()>(&X_Service::service1);
(service.*(func))();
std::cout << service.x << std::endl;
std::cin.get();
X_Service derp;
(derp.service1)();
std::cout << derp.x << std::endl;
return 0;
}
Итак, с самого начала auto
дал вам возможность сделать безопасный указатель без типа void (IService::*)()
также экземпляр самого объекта равен this->
независимо от того, от какой функции-члена какого класса вы невидимыми унаследованы. Единственная проблема заключается в том, что первая переменная экземпляра интерпретируется на основе первой переменной класса, от которого вы скрытно наследуете, что может привести к повреждению стека, если тип отличается.
Способы получения классного вывода, но неизбежно вызывает повреждение стека, вы можете сделать следующие забавные вещи.
class IService {
public:
char x;
};
Ваша IDE обнаружит повреждение стека вашего объекта IService, но получение вывода
65
A
того стоит, но вы увидите, что при этом возникнут проблемы скрытное наследование.
Я также использую компилятор 86x. Так что в основном все мои переменные выстроены. Скажем, например, если я добавлю int y выше int x в Iservice, эта программа выдаст ерунду. В основном это работает только потому, что мои классы совместимы в двоичном формате.