2013-06-04 18 views
2

我從頁面下面的清單:該運算符重載函數返回什麼?

#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會增加嗎?
如果這個問題很荒唐容易,請耐心等待,我還是個菜鳥。如果這還不夠信息,我可以提供實際來源

+10

'(AABB *)this'? '(&x)+ i'?什麼......遠離這個代碼。 – GManNickG

+0

是的,我的反應是一樣的:) –

+4

這個代碼(這是一個很好的做錯事情的例子)正在努力地以數組的形式訪問標量值(即_x_,_y_,_z_)。特別是'operator [](const long i)'使用x('&x')的地址和索引('i')來查找相應元素的內存地址,並返回它的值。 – radical7

回答

3

它沒有增加。因此,*((&x) + i)返回第i個標量。 x代表0,y代表1,z代表2。

+0

謝謝。你是第一個,所以這裏是你的綠色徽章 –

1

這是指針算術。

VECTOR結構,該SCALAR成員將可能(它不能保證。)依次出現在內存中,該代碼的作者正是利用了這隻需添加一個索引到第一構件存儲器地址在結構中(x)。

這是輸入如何映射到輸出:

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

這是一個pr但作者不安全的假設:V。
(填充字節,成員順序等)

+0

認真地,擊中這個人的臉。 –

+0

這是1999年10月18日的文章:) –

+1

這就解釋了它。我懷疑這個片段很舊:P –

3

這被稱爲指針算術。

在代碼中,&x取地址x這是一個指針;加上i表示指針增加了sizeof(x) * i。通常你這樣做是爲了達到和索引數組一樣的效果。舉例來說,如果你有

int arr[10]; 

然後通過有效地寫&arr[0] + i您索引到數組中i個整數。在某些情況下,可能會有一些其他類型的連續內存塊而不是標準數組。

這並不完全是在問題中發生的情況,因爲這裏沒有數組或其他此類內存塊。相反,代碼假定編譯器將計算VECTOR的內存佈局,使得x,yz將被放置在內存中,模擬陣列布局。

然而這種做法根據C++標準調用未定義的行爲,所以這種實施VECTOR是有缺陷的,並且不應當被使用。

+1

當然,沒有任何這樣的保證,結果是UB。 – GManNickG

+0

@GManNickG:即使有保證,這也會是UB,因爲技術上索引超出了界限,對嗎? – Jon

+0

很好地描述了謝謝。 –

2

operator[]中的操作是「指針算術」 - 您可以使用普通算術運算符(本例中爲+)使用指針(通常使用數組)來導航內存。

你可以看到這種技術在這裏的一些例子: http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/pointer.html

應當注意的是,如果SCALAR是一些非數組類型,那麼我認爲給出的代碼是「危險的」 ,因爲它假定x,yz將在鄰近的存儲器位置,這不能由標準C++保證。如果你試圖在不能保證這個假設的平臺上使用這個代碼,結果會是,operator[]最多會返回一些未定義的值,或者最壞的情況會導致分段錯誤。

+0

感謝您的鏈接! –