Указатель this
не сохраняется вдоль указателя на член (указатели на функции-члены являются частным случаем этого). Если вы просто делаете
void (MyObject::*f)( int, int ) = &MyObject::method_that_takes_two_ints;
тогда сохраняется только информация о том, какую функцию-член следует вызывать в объекте, который вы позднее должны будете предоставить. Если вы хотите вызвать его, вы должны передать объект, откуда компилятор получит указатель this
.
MyObject o; (o.*f)(1, 2);
Указатель на функцию-член - это просто указатель на член, тип которого (на который указывают) является типом функции. Стандарт гласит, что указатели на функции-члены не имеют своего собственного «типа функции-члена», на который они указывают, и который каким-то образом включает тип указателя this.
int main() {
typedef void fun() const;
fun MyObject::*mem_function_ptr =
&MyObject::const_method_that_takes_two_ints;
}
fun
в этом коде является типом функции. Тип, который имеет «нормальная» функция. Указатель на функцию, в отличие от указателя на функцию-член, является просто указателем на функцию такого типа:
void foo() { cout << "hello"; }
int main() {
typedef void fun();
fun * f = &foo;
}
Хотя указатель на функцию-член имеет дополнительный уровень указателя на член поверх этого типа функции.
Что-то о указателе this
и о том, как он относится к объекту, на который он указывает (не технический, а только теоретический материал):
Каждая функция-член имеет скрытый параметр, называемый implicit object parameter
, который имеет тип MyObject&
или MyObject const&
в зависимости от того, есть ли у вас функция-член const или nonstst. o
Объект, для которого вы вызываете функцию-член, - это implied object argument
, который передается параметру. В теории стандарта, составляющей правила, которые описывают, как вызываются функции-члены, неявный параметр объекта является первым скрытым параметром. Это концептуально и не означает, что это реальный случай в реализациях. Затем подразумеваемый объектный аргумент привязывается к этому неявному объектному параметру, возможно, вызывая неявные преобразования (поэтому, если вы вызываете функцию-член const для неконстантного объекта, квалификационное преобразование преобразуется из MyObject
в MyObject const&
. неконстантные функции - лучший выбор, чем константные функции для вызова неконстантных объектов). Например, в этом коде можно сказать:
struct A {
operator int() const { return 0; }
};
int main() {
A a;
int i = a; // implicit conversion using the conversion function
}
что подразумеваемый аргумент объекта a
типа A
связан с неявным параметром объекта типа A const&
, на объект которого затем указывает указатель this
, имеющий здесь тип A const*
. Важно отметить, что неявный параметр объекта является только теоретической конструкцией, чтобы формализовать, как составлены правила для вызова функции-члена (и конструкторы не включают их), в то время как указатель this фактически существует. this
является указателем, потому что когда был введен this
, C ++ еще не имел ссылок.
Надеюсь, это поможет вам понять этот вопрос.