2014-03-02 52 views
2

我試圖模擬緩存。給定數組時,我必須確定operator[](size_t i)是用於獲取數據還是設置它。我在它的簽名中爲const超載了它,並且沒有它的設置部分。強制編譯器選擇const運算符過載

我的問題是,因爲數組是動態分配的,所以只有非const operator[]被調用。例如:

class A {  
      int n; 
      double *v; 
    public: 
      A(int i) : n(i),v(new double[i]) {} 
      const double & operator[](int i) const { 
       cout<<"get"<<endl ; 
       return v[i]; 
      } 
      double& operator[](int i) { 
       cout<<"set"<<endl; 
       return v[i]; 
      } 
    }; 
    int main(){ 
     double pi = 3.14; 
     A a(10); 
     a[2] = pi; 
     pi = a[3]; 
    } 

結果是

set 
set 

但我希望打印

set 
get 
+2

然後,您將需要單獨的函數,因爲'const'或non-'const'函數的選擇並不關心您將如何處理它。如果你在非'const'對象上調用它,你會得到非''const'版本,對於'const'對象,你會得到'const'版本。當你做'a [3]'時,它不知道你不會分配它。它只是調用非''constst'函數,因爲'a'不是'const'。 –

回答

3

它沒有任何與數組被動態分配。您的變量a不是const,因此將調用非const函數。如果您有const B b(10);並確實b[3]const版本將被調用。

如果你真的想,你可以強制const版本轉換爲一const參考稱爲:

static_cast<const A&>(a)[3] 

(或者,創建一個參考變量,並調用它上)

+0

但'b [2] = pi;'在那種情況下不會編譯 – user3371583

+0

@ user3371583當然,這就是整個問題。由於對象是'const',所以'operator []'應該向其內部返回一個'const'引用,所以你不能指定它。 –

2

你已經發現了爲什麼operator[]對於類似緩存的操作來說是一個糟糕的「接口」,並且爲什麼每個人似乎都被std::map的行爲所困擾,因爲如果你試圖「索引」一個沒有創建新對象的行爲存在。

我會寫明確的getset方法,這樣你不會驚訝你的緩存類的用戶。