Когда это (это!= Это) в С++?

У меня очень странный вопрос.

У меня есть класс/функция:

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).