Когда это (это!= Это) в С++?
У меня очень странный вопрос.
У меня есть класс/функция:
class MCBSystem {
[...]
template <class Receiver>
void setCallBack(int i, Receiver* receiver, void(Receiver::*function)(void*)) {
iCallBacks.at(i) = new CallBack<Receiver>(receiver, function, this);
};
};
И я наследую его (умножаю) в другом классе:
class MenuBox : public OverlayBox, public HIDListener, public FANLib::MCBSystem {
[...]
};
Теперь, если я вызываю функцию setCallBack:
menuBox->setCallBack(MenuBox::CLICKED, this, &SubMain::widgetClicked);
тогда "menuBox" имеет значение 0x06cf22b8, но внутри "setCallBack", "this" равно 0x06cf2370.
Может кто-нибудь объяснить, что происходит на земле?
[EDIT:] Истинный вопрос: если мне нужно сохранить 'this' внутри 'setCallBack', как я могу проверить позже, что 'menuBox == this'?
Большое спасибо в advace!
Ответы
Ответ 1
Да, указатель this
должен быть исправлен, чтобы разрешить множественный полиморфизм наследования. В качестве приближения нулевого порядка можно считать, что экземпляр класса C
, который наследует от A
и B
, включает экземпляр A
, за которым следует экземпляр B
. Теперь, если у вас есть указатель на экземпляр C
и преобразовать его в экземпляр B
, указатель this
должен отличаться, потому что экземпляр B
находится после экземпляра C
в памяти. См. этот документ для углубленного обсуждения.
Маленькая тестовая программа:
#include <iostream>
struct A { int i; };
struct B { int j; };
struct C: A, B { };
#define PRINT(expr) std::cout << #expr " = " << expr << std::endl
int main() {
C* c = new C;
B* b = c;
PRINT(b);
PRINT(c);
PRINT(static_cast<B*>(c));
}
Ответ 2
Учитывая любой указатель на объект, он будет отличаться в зависимости от того, на что он сделан.
Внутри функции-члена MenuBox
, this
указывает на часть MenuBox
объекта, о котором идет речь.
Однако, в setCallBack
, он отображается в указателе на часть Receiver
объекта.
Другими словами, this
всегда будет равен this
, но для любого указателя p
static_cast<MenuBox>(p)
никогда не будет равным static_cast<Receiver>(p)
.