Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Can';这';指针不能与对象';什么是指针?_C++ - Fatal编程技术网

C++ Can';这';指针不能与对象';什么是指针?

C++ Can';这';指针不能与对象';什么是指针?,c++,C++,我最近在某个类中遇到了这个奇怪的函数: void* getThis() {return this;} 在后面的代码中,它有时会这样使用:bla->getThis()(其中bla是指向定义此函数的类的对象的指针) 我似乎不知道这有什么好处。是否存在指向对象的指针与对象的this(其中bla!=bla->getThis())不同的情况 这似乎是一个愚蠢的问题,但我想知道我是否遗漏了什么。不。是的,在有限的情况下 这看起来像是受到Smalltalk的启发,在Smalltalk中,所有对象都有一个yo

我最近在某个类中遇到了这个奇怪的函数:

void* getThis() {return this;}
在后面的代码中,它有时会这样使用:
bla->getThis()
(其中bla是指向定义此函数的类的对象的指针) 我似乎不知道这有什么好处。是否存在指向对象的指针与对象的
this
(其中
bla!=bla->getThis()
)不同的情况

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

不。是的,在有限的情况下

这看起来像是受到Smalltalk的启发,在Smalltalk中,所有对象都有一个
yourself
方法。在某些情况下,这可能会使代码更干净。正如注释注释,这看起来是一种奇特的方式,甚至在C++中实现这个习语。
在您的具体案例中,我会询问该方法的实际使用情况,看看它是如何使用的

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

这个习惯用法的一个潜在使用案例是,在将已知类型的对象存储为
void-const*
(或
void*
;此处的
const
正确性无关紧要)之后,能够恢复它们:如果您有一个复杂的继承层次结构,您不能将任何奇数指针强制转换为
void*
,并希望能够将其恢复为原始类型!也就是说,为了方便地获取,例如,指向
base
(来自下面的示例)的指针,并将其转换为
void*
,您可以调用
p->getThis()
,这比
static\u cast(p)
容易得多,并且可以使用
static\u cast(v)安全地将其转换为
base*
:您可以反转隐式转换,但仅当您回溯到原始指针的确切类型时。也就是说,
static\u cast(static\u cast(d))
其中
d
是指向派生自
base
类型的对象的指针是非法的,但是
static\u cast(d->getThis())
是合法的

首先,为什么地址会改变?在示例中,
base
是两个派生类的虚拟基类,但可能还有更多。其类实际上从
base
继承的所有子对象将在另一个派生类的对象中共享一个公共
base
主题(
concrete
,在下面的示例中)。此
base
子对象的位置相对于相应的派生子对象可能不同,具体取决于不同类的排序方式。因此,指向
base
对象的指针通常不同于指向从
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';
}
#包括
结构基
{
void const*getThis()const{返回此;}
};
结构派生1
:虚拟基地
{
INTA;
};
结构派生2
:虚拟基地
{
int b;
};
结构混凝土
:derived1
,被嘲笑
{
};
int main()
{
混凝土c;
derived2*d2=&c;
无效常数*dptr=d2;
void const*gptr=d2->getThis();

std::cout我在很多年前遇到过类似的东西。如果我没记错的话,当一个类操作同一个类的其他实例时需要它。一个例子可能是一个容器类,它可以包含自己的类型/(类?)。

这可能是重写this关键字的一种方法。 假设您有一个内存池,在程序开始时完全初始化,例如,您知道在任何时候您最多可以处理50条消息CMessage。 创建一个大小为50*sizeof(CMessage)(这个类可能是什么)的池,CMessage实现getThis函数

通过这种方式,您只需覆盖“this”即可访问池,而不是覆盖新关键字。 这也可能意味着对象可能被定义在不同的内存空间上,比如说在SRAM上,在启动模式下,然后在SDRAM上


在这种情况下,同一个实例可能会返回不同的值,以便在重写时通过程序执行此操作。

您的类可以有自定义的
操作符&
(因此
&a
可能不会返回
)。这就是存在的原因。

是否涉及模板?或继承?返回类型是否与包含函数的类的类型相同?因为如果不是这样的话,
getThis
调用什么上下文就没有意义了?看起来它是用于强制转换到
void*
。为什么它们不直接强制转换到
void*
我不知道。Y你会在别人的代码中看到一些有趣的东西。@Dave是的,总是在别人的代码中,当然不会在我们的代码中我从来没有打开过一个月的代码文件。我的代码是摇滚的。+ 1只是为了<代码> GRP部分。老实说,在20年的C++中,我从来没有见过这种结构需要的情况,但也许那只是我……@ SyAM我想不出一个实例,但是我的SimalTalk经验有限。我想它变成了。一种语言中的事物,其原因可能是或可能不适用于C++。
有可能
p0!=p1
!它所需要的只是
bla
是一个指向一个适当构造类型的指针。@DietmarKühl指出。我仍然不知道它的实际用途。@Dave:正如Steve Clamage所说的那样