关键字"this"的实际含义是什么?

What is the actual meaning of keyword "this"?

本文关键字:是什么 this 关键字      更新时间:2023-10-16

我有两个关于c++的问题:

在许多教科书中,关键字this是指向调用对象的指针。正确吗?

因为我喜欢玩编码,我写了以下简单的代码:

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();
}

上面的代码产生如下输出:

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()

如果this指向调用对象,由于调用对象是b, sizeof(*this)的第二行应该打印8而不是4吗?这里到底发生了什么?this被降级了吗?!!!!

如果this已经降级为Base类型,this->f()如何调用正确的函数?

void Base::g() {
    cout << "Base::g()" << endl;
    cout << "sizeof(*this) : " << sizeof(*this) << endl;
    this->f();
}
需要做的重要区别是sizeof编译时操作符,而不是运行时操作符。编译器将表达式sizeof(*this)解释为"this所指向的对象的大小",在Base::g的作用域中,该对象是类型为Base的对象。编译器会将这条语句重写为这样,因为它知道Base的大小是四个字节:
cout << "sizeof(*this) : " << 4 << endl;

Base不能看到/访问/知道任何作为派生对象一部分的东西,所以sizeof只报告对象对它可见的部分。更重要的是,Base的方法中的sizeof无法知道有或将有子类(毕竟,您可以在不重新编译Base的情况下对其进行子类化),因此它只能报告它所知道的部分。(sizeof是在编译时计算的,而不是运行时。)

调用正确的f函数,因为Base::f是虚函数。这告诉编译器,当请求对Base*->f()的调用时,被调用方的实际地址将在您调用其成员的实际对象的虚函数表中查找。

所讨论的this类型Base*,这就是sizeof(*this) == sizeof(Base)的原因,但它的虚函数表属于派生对象,因此对f的函数调用将转到覆盖

this是一个常值指针,指向该函数是非静态成员的对象。这意味着,要使this成为一个可行的值,它必须仅在类的非静态成员中使用。记住:必须使用对象实例来调用非静态成员函数(实例)。Function或instance-> Function);this是指向"instance"的指针。

的大小永远不是你期望的8的原因是因为gBase类的成员。对于g, this的类型是Base *const,因此*this的类型是Base&sizeof(Base)是4。即使它是一个虚拟成员,这也不会改变;g实现的类型总是Base *const。虚覆盖的版本会有不同的类型,但只有实现它们的类的类型。

this的类型不遵循多态性;

与函数定义时的类型完全一致且只有。