2011-04-28 39 views
1

我創建了一個結構類:C++超載[]操作不

struct a{ 
    int a1; 
    int a2; 
    int a3; 
}; 

有什麼辦法來創建一個函數,其中a[1]會以同樣的方式,我就可以給a1訪問通過數組?

編輯,我已經粘貼,我實際上做的部分:

struct lipid{ 
    particle mainPart; 
    bead * head; 
    bead * body; 
    bead * tail; 
    vec direction; 
    bead * operator[](int index){ 
    switch(index){ 
    case 0: return head; 
    case 1: return body; 
    case 2: return tail; 
    default: return body; 
    } 
    } 
}; 

珠和顆粒是我創造了另一種結構。它的工作原理...感謝

+2

了'結構'是一個類,它可以重載'[]'以及任何類的重載。但是,如果你只需要三個整數,爲什麼不使用'typedef int a [3]'? – delnan 2011-04-28 14:44:11

回答

1

正如delnan指出,你可以使用方法上的結構,就像類一樣。

所以:

struct a{ 
    int a1; 
    int a2; 
    int a3; 
    int &operator[](int i){ 
     switch(i){ 
     case 1: return a1; 
     case 2: return a2; 
     case 3: return a3; 
     default: return -1 
     } 
    } 
}; 
+0

我試過這個,但它返回的結構類型,而不是我想要的。我爲我的實際代碼編輯了我的消息,沒關係我找到了我的錯誤。 – Yotam 2011-04-28 15:26:02

4

最後一行11.8節(運算符重載,下標)在Stroustrup的 'C++程序設計語言' 的:

'An operator []() must be a member function.' 

所以,不,這是不可能的C++。

(儘管當然是struct是C++中的class,但我相信你的意思是你想struct a仍然是一個POD)

+1

只要它不是虛擬的,'a'仍然會是POD,即使有'operator []'。 – 2011-04-28 15:03:44

+0

@Steve:請參閱我的解決方案。我想知道你對此的評論。 – Nawaz 2011-04-28 15:17:46

0

好吧,如果你一定要,你可以解決它與工會,雖然你可在得到皺眉道:

union 
{ 
    struct 
    { 
     int a1; 
     int a2; 
     int a3; 
    }; 
    int a[]; // may need compiler-specific tweaking 
}; 

請注意,並非所有編譯器支持int a[],你可能得寫int a[0]甚至int a[3],這取決於編譯器/語言的方言。

+0

如果進入特定於實現的領域(使用一個聯合的一部分接着另一個聯合),我不會感到驚訝,儘管除非編譯器做了一些非常糟糕的佈局欺騙,否則應該保存。 – delnan 2011-04-28 14:50:54

+0

是的,就像我說的那樣,這不是世界上最好的事情,當其他人閱讀代碼時,最好有一個更好的解釋:-)但沒有開玩笑,我實際上已經在使用這樣的構造次,例如,它像魔術一樣在循環中批量加載DLL中的函數指針(例如在編寫自己的OpenGL/OpenAL/OpenCL加載器時)。 – Damon 2011-04-28 14:56:14

0

我們假設struct a位於某個庫中,並且您無法更改它,否則您會採用@ delnan的typedef建議(typedef int a[3])。

如果結構不使用多態,你可能濫用繼承和自己添加操作:

struct a_with_brackets : public a 
{ 
    int& operator[](int index) 
    { 
     switch(index) 
     { 
     case 1 : return a1; 
     case 2 : return a2; 
     case 3 : return a3; 
     } 
    } 
}; 
+0

Mark ...查看我的解決方案。我想知道你對此的評論。 – Nawaz 2011-04-28 15:13:11

0
struct a{ 
    int a1; 
    int a2; 
    int a3; 

    int & operator[](int i) { 
     if (i == 0) { 
     return a1; 
     } 
     else if (i == 1) { 
     return a2; 
     } 
     else if (i == 2) { 
     return a3; 
     } 
     else { 
     throw "index error"; 
     } 


}; 
1

由於operator [] must be a member function,如由他人注意,你不能這樣做。

但我想出了所謂subscriptable以下包裝類,它可以幫助你模擬它:

class subscriptable 
{ 
    A & a; 
    public: 
    subscriptable(A & a) : a(a) {} 
    subscriptable(const subscriptable & s) : a(s.a) {} 
    int & operator[](int i) 
    { 
     if (i < 0 || i > 2) throw "index out of range"; 
     else if (i == 0) return a.a1; 
     else if (i == 1) return a.a2; 
     else return a.a3; 
    } 
    operator A &() { return a; } 
}; 
void print(A & a) 
{ 
    subscriptable s = a; //a implicitly converts to subscriptable 
    for (int i = 0 ; i < 3 ; i++) 
     std::cout << s[i] << std::endl; 
} 
int main() 
{ 
     A a; 
     subscriptable s = a; //a implicitly converts to subscriptable 
     for (int i = 0 ; i < 3 ; i++) 
      s[i] = (i + 1) * 100; 
     print(s); //s implicitly converts to A 
     return 0; 
} 

輸出:

100 
200 
300 

在線演示:http://www.ideone.com/ymmg1

+0

似乎是合理的,如果我們不允許修改'a'的定義,儘管我可能會使用'int *'數組而不是矢量。根據預期用途,您可能希望將其賦值爲可賦值的(所以要麼使用指針而不是對's'的引用,以便它是可重新引用的引用,否則實現副本'operator ='以複製到底層結構體,無論哪個你想要的語義)。 – 2011-04-28 16:07:24

+0

@Steve:我意識到我甚至不需要'int *'。我的更新版本似乎比以前更好。你有什麼意見? – Nawaz 2011-04-28 16:48:57