Когда (это! = Это) в C ++? - PullRequest
11 голосов
/ 29 июня 2010

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

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

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'?

Большое спасибо за продвижение!

Ответы [ 2 ]

17 голосов
/ 29 июня 2010

Да, указатель 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));
}
1 голос
/ 29 июня 2010

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

Внутри функции-члена MenuBox, this указывает на часть MenuBoxрассматриваемый объект.

Однако в setCallBack он приводится к указателю на Receiver часть объекта.

Другими словами, this будетвсегда равно this, но для любого указателя p static_cast<MenuBox>(p) никогда не будет равно static_cast<Receiver>(p).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...