指针'this + 1'在C++中引用了什么?

Ath*_*S21 41 c++

我在浏览Sequitur G2P的代码时发现了一段非常奇怪的代码:

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

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

Jon*_*son 59

大概this是数组的一部分,所以this+1会引用该数组中的下一个对象.

  • 那么这个操作不是很危险吗?因为无法保证此对象包含在数组中,或者下一个对象属于同一个类 (37认同)
  • 不,只是做'this + 1`不是UB.但是,使用` - > finalized'取消引用结果. (28认同)
  • @ AtheS21:C++数组是同构的.如果有下一个元素,则它具有相同的类型.这只是形成风险的"没有下一个因素". (8认同)
  • 它实际上是`std:vector <>的一部分,不是C风格数组的一部分,但标准也保证了这些内存的连续内存.这段代码是私有实现类的一部分,实际上只从一个地方调用.物体的构造保证了它的安全. (6认同)
  • 但这绝对是最后一个对象的UB.对吗? (5认同)
  • @MSalters我不认为同质性足以避免AtheS21带来的东西.考虑Derived类型的同类数组,而评估`(this + 1)`的函数是Base类型的函数,它小于Derived.话虽这么说,这是C++.通过利用开发人员拥有的先验信息,一半的乐趣就是能够进行疯狂的优化! (5认同)
  • @ AtheS21嗯,你必须保证自己下一个对象在连续的内存中具有正确的对齐方式,并且是兼容的类型. (3认同)

Tas*_*Tas 33

this只是一个引用对象的指针.由于它是一个指针,因此您可以应用指针算法甚至数组索引.

如果对象是数组中的元素,则this+1指向数组中的下一个对象.

如果不是,那么它只是将该内存中的任何内容视为与对象相同,除非它是相同类型,否则将是未定义的行为.

  • "如果不是(一些明确的陈述)"不,未定义的行为是未定义的.它可以做*任何事情*.如果编译器可以证明你总是走到最后它可以发出一个空程序,或者一个格式化你的高清或任何它想要的程序 (11认同)
  • @MM:缺乏定义的行为也是未定义的行为.C++标准没有枚举所有未定义的行为.(C,IIRC,在附录中). (10认同)
  • @MM那是错的.如果取消引用指向超出数组末尾的指针,则表示您具有UB.(如果该指针碰巧比较相同类型的另一个对象的地址,你可能不会崩溃,但你仍然有UB - 除了我找不到章节和经文.) (5认同)
  • @ AtheS21不,UB比这更深.它控制编译器可用的优化; 如果某些东西是UB,编译器可以将其视为"这将永远不会发生",并相应地进行优化,包括(如Caleth所说)将整个程序改为"返回1"或其他任何东西.例如,如果取消引用指针并使用相同指针的空值检查,编译器将断定代码块将永远不会执行,因为指针不可能为空,因为您尝试取消引用它.但如果取消引用被优化掉了,你就不会遇到运行时错误:) (2认同)

Tho*_* G. 5

因为它是NLP,所以优化内存管理是有意义的.我假设您也发现了重载的新/删除方法.

this + 1构造假设所有对象都驻留在数组中.方法的名称'childrenEnd'表示它返回指向当前节点的子节点结尾的地址的指针.

因此,您正在研究树结构的实现.所有兄弟姐妹都和他们的孩子相邻.