该运算符重载函数返回什么?

时间:2013-06-04 22:15:28

标签: 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( long i ) const
    {

      return ((AABB*)this)->P[i] - ((AABB*)this)->E[i];
    }
    // ...
};

现在我不明白的是,min()使用long值访问的是什么。 我已查看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 )
  {

那么为什么x值引用会增加i
如果这个问题很荒谬,请耐心等待我,我还是个菜鸟。如果这还不够,我可以提供实际的来源

4 个答案:

答案 0 :(得分:3)

它没有增加。

&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) + i)返回第i个标量。 x代表0,y代表1,z代表2。

答案 1 :(得分:3)

这称为指针算法。

在代码中,&x采用x的地址作为指针;添加i表示指针增加sizeof(x) * i。通常,您可以实现与索引到数组相同的效果。例如,如果你有

int arr[10];

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

这不是所讨论的情况中发生的情况,因为这里没有数组或其他此类内存块。相反,代码假定编译器将计算VECTOR的内存布局,以便将xyz放在内存中,模拟数组布局。

然而,这种做法会根据C ++标准调用未定义的行为,因此VECTOR的此实现存在缺陷,不应使用。

答案 2 :(得分:2)

operator[]中完成的操作是“指针算术” - 在这里使用普通的算术运算符(在这种情况下为+)使用指针(通常使用数组)来导航内存。

您可以在此处查看此技术的更多示例: http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/pointer.html

应该注意的是,如果SCALAR是一些非数组类型,那么我认为给出的代码是“危险的”,因为它假设{{1 },xy将位于相邻的内存位置,这是标准C ++无法保证的。结果是,如果您尝试在不保证此假设的平台上使用此代码,那么z最多会返回一些未定义的值,或者最坏情况会导致分段错误。

答案 3 :(得分:1)

那是指针算法。

VECTOR结构中,SCALAR成员可能(无法保证。)连续出现在内存中,该代码的作者利用了只需在结构(x)的第一个成员的内存地址中添加一个索引。

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

  • 0 ... *(&x + 0) ... x
  • 1 ... *(&x + 1) ... y
  • 2 ... *(&x + 2) ... z

然而,这是作者非常不安全的假设:V。
(填充字节,成员顺序等......)