2013-10-07 36 views
17

我無法區分運算符get和set之間的區別[]。我需要說明這些函數調用之間的區別。運算符[] C++獲取/設置

cout << data[5]; 
data[5] = 1; 

我使用了它,並且我發現的答案仍然沒有幫助。人們建議通過添加const使方法的簽名不同。我這樣做了,他們仍然都用同樣的方法。

有我用過的簽名:

const T& operator[](unsigned int index) const; 
T& operator[](unsigned int index); 

我在做什麼錯?

+3

您可能想要查找*代理對象*,這通常用於區分讀取和寫入。 – templatetypedef

+0

請參見Scott Meyers [更有效的C++]中的第30項「代理類」(http://www.amazon.com/More-Effective-Improve-Programs-ebook/dp/B004VSMDNY/ref=la_B004BBEYYW_1_2?s=books&ie= UTF8&qid = 1381129998&sr = 1-2)進行廣泛的討論,包括代理類可以爲您提供的令人驚訝的缺陷(與用戶定義的轉換有關)。該材料是[強制性閱讀](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 – TemplateRex

回答

16

的解決方案是使用「代理」對象,將延遲實際操作:

#include <vector> 
#include <iostream> 

template<typename T> 
struct MyArray { 
    std::vector<T> data; 
    MyArray(int size) : data(size) {} 

    struct Deref { 
     MyArray& a; 
     int index; 
     Deref(MyArray& a, int index) : a(a), index(index) {} 

     operator T() { 
      std::cout << "reading\n"; return a.data[index]; 
     } 

     T& operator=(const T& other) { 
      std::cout << "writing\n"; return a.data[index] = other; 
     } 
    }; 

    Deref operator[](int index) { 
     return Deref(*this, index); 
    } 
}; 

int main(int argc, const char *argv[]) { 
    MyArray<int> foo(3); 
    foo[1] = 42; 
    std::cout << "Value is " << foo[1] << "\n"; 
    return 0; 
} 

簡單const因爲您可能需要從非常量實例中讀取,所以無法使用該屬性,這就是您必須延遲操作的原因:分配發生在「訪問和編譯器之後」之後告訴你訪問是否將被用作分配目標。

因此,這個想法是,在訪問時,您只需存儲已請求的索引,並等待知道是正在進行讀取還是寫入操作。通過提供從代理到T的隱式轉換運算符,您知道何時發生讀取操作,通過向T中的代理提供並分配運算符,您知道何時發生寫入操作。

0

const版本的廣告operator[]將呼籲const數據對象:

const Data data; 
cout << data[5]; 
3

const版本意味着如果在調用它的對象是const,你可以調用該版本的[]運營商,只有該版本。

但是,如果對象不是const,則可以調用[]運算符的兩個版本,但編譯器將選擇非const版本。換句話說,對於非const對象,操作符的非const版本可以充當「setter」或「getter」。這就是爲什麼在你的例子中,在這兩種情況下調用相同的版本,因爲你的data對象不是const。

你將不得不做這樣的事情:

const Data& data_cref = data; 
cout << data_cref[5]; // calls the const version of operator[] 

Data& data_ref = data; 
data_ref[5] = 1;  // calls the non-const version of operator[] 
1

爲了與標普通意義兼容,下標運算符通常返回到即取元素的引用。 通過返回引用,可以在任務的任一側使用下標。

因此,定義該運算符的const和nonconst版本通常也是一個好主意。當應用於對象時,下標應該返回對const的引用,以便將其分配給返回的對象。

---- C++入門,第五版