开发者

What is the actual meaning of keyword "this"?

开发者 https://www.devze.com 2023-03-18 09:47 出处:网络
I have two questions related to C++: In many textbooks, the keyword this is a pointer to the calling object.Correct?

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消