C++ “关键字”的实际含义是什么;这是什么;?

C++ “关键字”的实际含义是什么;这是什么;?,c++,C++,我有两个关于C++的问题: 在许多教科书中,关键字this是指向调用对象的指针。对吗 由于我喜欢玩编码,我编写了以下简单代码: struct Base { void g(); virtual void f(); }; void Base::f() { cout << "Base::f()" << endl; } void Base::g() { cout << "Base::g()" << endl; 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();
}
如果
this
指向调用对象,那么
sizeof(*this)
的第二行是否应该打印8而不是4,因为调用对象是
b
?这里到底发生了什么?这是不是已经降级了


如果
this
已降级为type
Base
,那么
this->f()
如何调用正确的函数?我真的很困惑。

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

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


的类型不遵循多态性;它完全且仅具有定义函数时使用的类型。

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

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


所讨论的
类型
Base*
,这就是为什么
sizeof(*this)==sizeof(Base)
,但它的vtable属于派生对象,因此对
f
的函数调用进入覆盖。

尝试在派生::f()中添加对sizeof(*this)的调用。看看这能带来什么。Base::g()中的调用不知道它是子类的一部分。在这种情况下,*这合法地引用了Base,而不是派生的。您希望编译时如何计算
sizeof(*this)
?它与
sizeof(Base)
没有什么不同。即使
g
是虚拟的,也没关系,因为
g
从来不会被派生类重写,这不是为了澄清:即使
g
是虚拟的,
sizeof(*this)
Base::g()中始终是4
不管它是通过派生类型调用的(例如,如果虚拟
g()
未被重写)。我知道这是您在最后一句中所说的,但是第二段可能会让读者认为
sizeof(*this)
即使在
g()
的基本实现中也会“遵循”派生类型。哦,您是对的。我修改了代码以打印
this
的值,而不是
sizeof(*this)
,并将其与&b和&a进行比较。答案符合我的期望。嗯。。谢谢。
void Base::g() {
    cout << "Base::g()" << endl;
    cout << "sizeof(*this) : " << sizeof(*this) << endl;
    this->f();
}
void Base::g() {
    cout << "Base::g()" << endl;
    cout << "sizeof(*this) : " << sizeof(*this) << endl;
    this->f();
}
cout << "sizeof(*this) : " << 4 << endl;