C++ 这个运算符重载函数返回什么?

C++ 这个运算符重载函数返回什么?,c++,reference,operator-overloading,square-bracket,C++,Reference,Operator Overloading,Square Bracket,我从一个页面上看到以下列表: #include "vector.h" // An axis-aligned bounding box class AABB { public: VECTOR P; //position VECTOR E; //x,y,z extents AABB( const VECTOR& p, const VECTOR& e): P(p) ,E(e) {} // ... const SCALAR min( l

我从一个页面上看到以下列表:

#include "vector.h"

// An axis-aligned bounding box
class AABB
{
  public:
    VECTOR P; //position
    VECTOR E; //x,y,z extents

    AABB( const VECTOR& p, const VECTOR& e): P(p) ,E(e) {}

    // ...

    const SCALAR min( long i ) const
    {

      return ((AABB*)this)->P[i] - ((AABB*)this)->E[i];
    }
    // ...
};
现在我不明白的是,min()用一个长值访问什么。 我查看了
vector.h
,发现方括号运算符重载:

class VECTOR
{
  public:
    SCALAR x,y,z; //x,y,z coordinates

    //...

    //index a component
    //NOTE: returning a reference allows
    //you to assign the indexed element
    SCALAR& operator [] ( const long i )
    {
      return *((&x) + i);
    }
    //...
};
后来它被用作:

// each axis
for( long i=0 ; i<3 ; i++ )
{
  if( A.max(i)<B.min(i) && v[i]<0 )
  {
//每个轴
对于(长i=0;i它不是递增的

&x  //<- address of member x
(&x) + i //<- address of member x shifted right by i SCALAR's
*((&x) + i) // the scalar value at that point

&x/这是指针算法

向量
结构中,
标量
成员将很可能(不保证)连续出现在内存中,该代码的作者利用了这一点,只需将索引添加到结构中第一个成员的内存地址(
x

这是输入映射到输出的方式:

  • 0
    ..
    *(&x+0)
    ..
    x
  • 1
    ..
    *(&x+1)
    ..
    y
  • 2
    ..
    *(&x+2)
    ..
    z
然而,这是作者的一个相当不安全的假设:V.

(填充字节、成员顺序等…)

这称为指针算术

在代码中,
&x
获取
x
的地址,这是一个指针;向其中添加
i
意味着指针将递增
sizeof(x)*i
。通常这样做是为了达到与索引到数组中相同的效果。例如,如果

int arr[10];
然后通过写入
&arr[0]+i
可以有效地索引到数组中的
i
th整数。在某些情况下,可能存在其他类型的连续内存块,而不是标准数组

这与所讨论的情况不完全相同,因为这里没有数组或其他类似的内存块。相反,代码假定编译器将计算
VECTOR
的内存布局,这样
x
y
z
将被放置在内存中,模拟数组布局


但是,这种做法调用C++标准的未定义行为,所以向量的实现是有缺陷的,不应该使用。

< P>在Talm []/Cudio中所做的操作是“指针算术”——在这里使用正常算术运算符(<代码> +/COD>)使用指针导航内存(通常使用数组)

您可以在此处看到更多此技术的示例:


需要注意的是,如果
SCALAR
是某种非数组类型,那么我认为给出的代码是“危险的”,假定代码“> x< /代码>,<>代码> y>代码>代码> z代码>代码,将在相邻的内存位置,这不是标准C++所保证的。如果你试图在一个不能保证这个假设的平台上使用这个代码,结果就是<代码>操作符[]。
充其量会返回一些未定义的值,或者在最坏的情况下会导致分段错误。

(AABB*)这
(&x)+i
?什么…从这段代码中跑掉了。是的,我的反应是一样的:)这段代码(这是一个错误操作的好例子)正在努力访问标量值(即x,y,z)作为一个数组。特别是,
运算符[](const long i)
使用x的地址(
&x
)以及索引(
i
)来查找相应元素的内存地址,并返回其值。此代码产生未定义的行为,填充可能导致字段值之间出现漏洞。不要这样做,也不要对编写它的程序员大喊大叫。可能是我,但我不明白你的问题是什么。为什么
x
参考增加了
i
?因为
i
用于选择要返回的
x
y
z
。这是你的问题吗?@GManNickG:即使有保证,也会是UB,因为技术索引超出了范围,对吗?需要补充的是:这种行为未定义的原因是编译器有时会更改间距,甚至顺序,在数据段中设置变量以提高性能-这称为内存对齐。特别是在地址空间不同的机器上,它会发生变化。@Jon:是的,说得好。我们只保证
&x<&y<&z
(在代码< > Tayl Roalees:实际上在代码>结构> /CODE中,它只是C++中代码< >类< />的别名,保证成员的顺序遵循声明的顺序。当创建C时,通常将结构直接写入文件或网络,这样就不希望优化器移动成员。nx,很高兴知道。填充是否也一样?是否没有带
结构的填充?
?这是1999年10月18日的一篇文章:)解释了这一点。我怀疑这段代码相当古老:PThanks。你是第一个,这是你的绿色徽章