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

时间:2011-07-05 21:55:14

标签: c++

我有两个与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指向调用对象,那么sizeof(*this)的第二行是否应该打印8而不是4,因为调用对象是b?这里到底发生了什么? this已被降级了吗?!!!!

如果将this降级为Basethis->f()如何调用正确的函数?我真的很困惑。

4 个答案:

答案 0 :(得分:12)

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;

答案 1 :(得分:1)

Base无法查看/访问/了解派生对象的任何内容,因此sizeof仅报告对象可见的部分。更重要的是,sizeof方法中的Base无法知道是否存在子类(您可以继承Base而不重新编译它,所以它可以'报告除了它知道的部分之外的任何事情。 (sizeof在编译时计算,而不是在运行时计算。)

答案 2 :(得分:0)

this是一个常量值指针,指向该函数是非静态成员的对象。这意味着,要使this成为可行值,它必须仅用于类的非静态成员。请记住:您必须使用对象实例来调用非静态成员函数(instance.function或instance-&gt;函数); this是指向“实例”的指针。

大小永远不是你期望的8是因为g是类Base的成员。对于gthis的类型为Base *const,因此*this的类型为Base&sizeof(Base)是4.即使它是虚拟成员,也不会改变; g实施的类型始终为Base *const。实际上被覆盖的版本将具有不同的类型,但只有实现它们的类的类型。

this的类型不遵循多态性;它完全和定义函数的类型。

答案 3 :(得分:0)

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

有问题的this类型Base*,这就是sizeof(*this) == sizeof(Base)的原因,但它的vtable属于派生对象,因此函数调用到f转到覆盖。