C++ 指针';这+;1';参见C++;?

C++ 指针';这+;1';参见C++;?,c++,C++,我在浏览的代码中发现了一行非常奇怪的代码: public: ... const Node *childrenEnd() const { return (this+1)->finalized.firstChild_; } 我知道这个是指向当前对象的指针,因为它是一个指针,所以这个操作是完全合法的,但是这个+1实际上指的是什么?大概这个是数组的一部分,因此,this+1将引用该数组中的下一个对象。此只是一个指向该对象的指针。因为它是指针,所以可以应用指针算法,甚至数组索引 如

我在浏览的代码中发现了一行非常奇怪的代码:

public:
    ...
    const Node *childrenEnd() const { return (this+1)->finalized.firstChild_; }

我知道
这个
是指向当前对象的指针,因为它是一个指针,所以这个操作是完全合法的,但是
这个+1
实际上指的是什么?

大概
这个
是数组的一部分,因此,
this+1
将引用该数组中的下一个对象。

只是一个指向该对象的指针。因为它是指针,所以可以应用指针算法,甚至数组索引

如果此对象是数组中的元素,
此+1
将指向数组中的下一个对象


如果不是,那么它只是将内存中的任何东西与这个对象一样对待,这将是未定义的行为,除非它是相同的类型。

因为它是NLP,所以优化内存管理是有意义的。我假设您也会发现重载的new/delete方法

this+1构造假定所有对象都驻留在一个数组中。该方法的名称“Childrend”表示它返回指向当前节点子节点末尾地址的指针

因此,您将看到一个树结构的实现。所有的兄弟姐妹都是相邻的,他们的子女也是如此。C++中的“+ 1”这个词的“< / P > < P>”意思是:

如果“this”对象是另一个对象的成员,它将指向在“this”对象变量之后声明的父对象下一个变量的地址:

例如:

class B
{
public:
    void* data()
    {
        return this + 1;
    }
};

class A
{
public:
    B m_b;
    char m_test;
};

int main(int argc, char* argv[])
{
    A a;
    a.m_test = 'H';

    void* p = a.m_b.data();
    char c;

    memcpy(&c, p, sizeof(char));
    return 0;
}
c等于H


长话短说,它允许访问父类数据,而无需将父类指针传递给子类。在这个例子中,这个+1指向A类的m_测试成员。

实际上,有一种情况,当这个东西可以使用时。我不建议使用这种方法,但它确实有效

我相信,在NLP代码中,它是这样使用的:

当您希望对象表现为集合(数组等)并将其与基于范围的数组等类似使用时,可以使用以下技巧:

struct Obj {
...
Obj* begin() { return this; }
Obj* end() { return this+1; }
...
}
现在,您可以在例如基于范围的for循环中使用此对象。。。
有时所有必要的。。。但即便如此,您最好使用“nullptr”甚至进行重构,而不是使用这个技巧。

那么这个操作不是非常危险吗?因为不能保证这个对象以数组的形式出现,或者下一个对象属于同一个类,但是对于最后一个对象,这绝对是UB。对吗?不,仅仅做
this+1
不是UB。用<代码> ->最终确定来取消结果。@ AsTest21:C++数组是同质的。如果有下一个元素,则它具有相同的类型。只有“无下一个元素”才构成风险。它实际上是
std:vector
的一部分,不是C样式数组的一部分,但标准也保证了这些元素的连续内存。这段代码是私有实现类的一部分,实际上只从一个地方调用。对象的构造保证了它的安全性。是的,我看到了问题所在,但是因为这是NLP中一个非常有名的工具的代码,我认为这样做一定有很好的理由。这是我第一次看到这样的代码“如果不是(某个确定的语句)”,不,未定义的行为是未定义的。它可以做任何事。如果编译器能证明你总是走到尽头,它可能会发出一个空程序,或者一个格式化你的硬盘或其他任何东西的程序wants@M.M:缺少定义的行为也是未定义的行为。C++标准没有枚举所有未定义的行为。(C是的,IIRC,在附录中)。@M.M这是错误的。如果取消引用指向数组末尾以外的指针,则有UB。(如果该指针恰好与同一类型的另一个对象的地址相比较,你可能不会崩溃,但你仍然有UB-除非我找不到这方面的章节。)@AtheS21不,UB比这更深。它控制编译器可用的优化;如果是UB,编译器可以将其视为“这永远不会发生”,并进行相应的优化,包括(如Caleth所述)将整个程序更改为
return 1
或其他任何形式。例如,如果您取消引用一个指针,然后对同一指针执行null检查,编译器将得出结论,代码块将永远不会执行,因为指针不可能为null,因为您尝试取消引用它。但是,如果优化引用被排除在外,则不会产生运行时错误:)C++中的一个问题,以及原因智能指针被添加到标准库中,就是原始指针的角色太多。作为迭代器和拥有句柄。然而,这个代码片段似乎对这种歧义及其滥用很感兴趣。它只在这里使用
returnbinarysearch(childrenBegin(),childrenEnd()-1,t)
-1
有区别吗?@JeffUK不,没有区别,如果
这个+1
指向不同的东西,但仍然试图与
->最终确定的
解除引用,那么它会立即崩溃该代码会伤害我的眼睛。我希望这是在一个非常受控的环境中调用的。我认为新标题不合适,
this+1
不是增量,
this++
是增量。显然,不能在C++中重新分配<代码>这个< /COD>值。我回到这个问题上来,被标题的非意义所迷惑,认为这是另一个问题。