gpt4 book ai didi

c++ - 'this' 指针可以与对象的指针不同吗?

转载 作者:IT老高 更新时间:2023-10-28 22:20:09 26 4
gpt4 key购买 nike

我最近在某个类(class)遇到了这个奇怪的功能:

void* getThis() {return this;}

稍后在代码中有时会这样使用:bla->getThis()(其中 bla 是指向此函数所在类的对象的指针被定义为。)而且我似乎无法意识到这有什么好处。是否存在指向对象的指针与对象的 this 不同的情况(其中 bla != bla->getThis())?

这似乎是一个愚蠢的问题,但我想知道我是否在这里遗漏了什么..

最佳答案

当然,指针值可以不同!下面是一个演示问题的示例(您可能需要在您的系统上使用 derived1 而不是 derived2 以获得差异)。关键是 this指针通常在涉及虚拟多重继承时进行调整。这可能是一种罕见的情况,但它会发生。

这个习惯用法的一个潜在用例是能够在将已知类型的对象存储为 void const* 后恢复它们。 (或 void*const 的正确性在这里无关紧要):如果你有一个复杂的继承层次结构,你不能只将任何奇数指针强制转换为 void*并希望能够恢复到原来的类型!也就是说,为了容易获得,例如,指向 base 的指针。 (来自下面的示例)并将其转换为 void* , 你会调用 p->getThis()这对 static_cast<base*>(p) 来说要容易得多并获得 void*可以安全地转换为 base*使用 static_cast<base*>(v) :您可以反转隐式转换,但前提是您转换回原始指针来自的确切类型。也就是说,static_cast<base*>(static_cast<void*>(d))在哪里 d是指向从 base 派生的类型的对象的指针是非法的,但 static_cast<base*>(d->getThis())是合法的。

现在,为什么首先要更改地址?在示例中 base是两个派生类的虚拟基类,但可能还有更多。其类实际上继承自 base 的所有子对象将共享一个共同点base进一步派生类的对象中的主体(concrete 在下面的示例中)。这个位置base子对象相对于相应的派生子对象可能不同,具体取决于不同类的排序方式。结果,指向 base 的指针object 通常不同于指向虚拟继承自 base 的类的子对象的指针。 .如果可能,相关偏移量将在编译时计算,或者在运行时来自诸如 vtable 之类的东西。沿继承层次结构转换指针时会调整偏移量。

#include <iostream>

struct base
{
void const* getThis() const { return this; }
};

struct derived1
: virtual base
{
int a;
};

struct derived2
: virtual base
{
int b;
};

struct concrete
: derived1
, derived2
{
};

int main()
{
concrete c;
derived2* d2 = &c;
void const* dptr = d2;
void const* gptr = d2->getThis();
std::cout << "dptr=" << dptr << " gptr=" << gptr << '\n';
}

关于c++ - 'this' 指针可以与对象的指针不同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18368594/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com