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

发布于 2024-11-19 00:12:48 字数 1190 浏览 1 评论 0原文

我有两个与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 已降级为 Base 类型,this->f() 如何调用正确的函数?我真的很困惑。

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, 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

飘落散花 2024-11-26 00:12:48
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;
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;
灯角 2024-11-26 00:12:48

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

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

心的憧憬 2024-11-26 00:12:48

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

相关 this类型Base*,这就是为什么 sizeof(*this) == sizeof(Base)< /code>,但其 vtable 属于派生对象,因此对 f 的函数调用将进行覆盖。

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.

若无相欠,怎会相见 2024-11-26 00:12:48

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

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

this 的类型不遵循多态性;它完全且具有定义该函数的类型。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文