Идентификация this
"Не все ли равно, о чем спрашивать, если ответа все равно не получишь, правда?"
Льюис Кэрролл. Алиса в стране чудес
Указатель this – это настоящий "золотой ключик" или, если угодно, "спасательный круг", позволяющей не утонуть в бурном океане ООП. Именно благодаря this возможно определять принадлежность вызываемой функции к тому или иному экземпляру объекта. Поскольку, все не виртуальные функции объекта вызываются непосредственно - по фактическому адресу, объект как бы "расщепляется" на составляющие его функции еще на стадии компиляции. Не будь указателей this – восстановить иерархию функций было бы принципиально невозможно!
Таким образом, правильная идентификация this очень важна. Единственная проблема – как его отличить от указателей на массивы и структуры? Ведь идентификация экземпляра объекта осуществляется по указателю this (если на выделенную память указывает this, это – экземпляр объекта), однако, сам this по определению это указатель, ссылающийся на экземпляр объекта. Замкнутый круг! К счастью, есть одна лазейка… Код, манипулирующий указателем this, весьма специфичен, что и позволяет отличить this ото всех остальных указателей.
Вообще-то, у каждого компилятора свой "почерк", который настоятельно рекомендуется изучить, дизассемблируя собственные Cи++ программы, но существуют и универсальные рекомендации, приемлемые к большинству реализацией. Поскольку, this – это неявной аргумент каждой функции-члена класса, то логично отложить разговор о его идентификации до главы "Идентификация аргументов функций", здесь же мы дадим лишь краткую сводную таблицу, описывающую механизмы передачи this различными компиляторами:
Компилятор | тип функции | ||||||||
Default | fastcall
| cdecl | stdcall | PASCAL | |||||
Microsoft Visual C++ | ECX | через стек последним аргументом функции | через стек первым аргументом | ||||||
Borland C++ | EAX | ||||||||
WATCOM C |
Таблица 1 Механизм передачи указателя this в зависимости от реализации компилятора и типа функции