What is the actual meaning of keyword "this"?
I have two questions related to C++:
In many textbooks, the keyword this
is a pointer to the calling object. Correct?
As i like to play with coding, 开发者_Python百科i wrote the following simple code:
struct Base
{
void g();
virtual void f();
};
void Base::f() {
cout << "Base::f()" << endl;
}
void Base::g() {
cout << "Base::g()" << endl;
cout << "sizeof(*this) : " << sizeof(*this) << endl;
this->f();
}
struct Derived : public Base
{
int d;
void f();
};
void Derived::f()
{
cout << "Derived::f()" << endl;
}
int main()
{
Base a;
Derived b;
cout << "sizeof(a) : " << sizeof(a) << endl;
cout << "sizeof(b) : " << sizeof(b) << endl;
a.g();
b.g();
}
The above code produces the following output:
sizeof(a) : 4
sizeof(b) : 8
Base::g()
sizeof(*this) : 4
Base::f()
Base::g()
sizeof(*this) : 4 // why 4 bytes not 8 bytes?????????
Derived::f()
If this
is pointing to the calling object, should the second line of sizeof(*this)
print 8 instead of 4 since the calling object is b
? What actually is happening here? Is this
has been demoted?!!!!
If this
has been demoted to type Base
, how this->f()
invokes the correct function? I am really confused.
void Base::g() {
cout << "Base::g()" << endl;
cout << "sizeof(*this) : " << sizeof(*this) << endl;
this->f();
}
The important distinction that needs to be made is that sizeof
is a compile-time operator, not a runtime operator. The compiler interprets the expression sizeof(*this)
as "the size of the object pointed to by this
", which, in the scope of Base::g
would be an object of type Base
. The compiler will essentially rewrite that statement as this, because it knows that the size of Base
is four bytes:
cout << "sizeof(*this) : " << 4 << endl;
Base
can't see/access/know about anything that's part of derived objects, so sizeof
only reports the part of the object that is visible to it. More to the point, sizeof
in a method of Base
can't know that there are or will be subclasses (you can subclass Base
without recompiling it, after all) so it can't report on anything but the part it knows about. (sizeof
is computed at compile time, not run time.)
The correct function f
is called because Base::f
is virtual. This tells the compiler that when a call to Base*->f()
is requested, the actual address of the callee is looked up in the vtable of the actual object whose member you invoke.
The type of the this
in question is Base*
, which is why sizeof(*this) == sizeof(Base)
, but its vtable belongs to a derived object and hence the function call to f
goes to the override.
this
is a constant value pointer to the object that the function is a non-static member of. Which means that, for this
to be a viable value, it must be used only in non-static members of a class. Remember: you must use an object instance to call a non-static member function (instance.function or instance->function); this
is a pointer to "instance".
The reason the size is never the 8 that you expect is because g
is a member of the class Base
. For g
, this
is of type Base *const
, and therefore *this
is of type Base&
. The sizeof(Base)
is 4. Even if it were a virtual member, this would not change; the type for that implementation of g
would always be Base *const
. Virtually overridden versions would have different types, but only the type of the class that implements them.
this
's type does not follow polymorphism; it has exactly and only the type that the function was defined with.
精彩评论