2011-04-23 17 views
4

我定義了兩個版本的重載operator[]函數的類arrayptr是指向array對象的第一個元素的指針。const重載的operator []函數及其調用

int& array::operator[] (int sub) { 
    return ptr[sub]; 
} 

int array::operator[] (int sub) const { 
    return ptr[sub]; 
} 

現在,如果我定義了一個const對象integer1第二功能只能叫.....但如果我做一個非const對象,然後如下調用:

cout << "3rd value is" << integer1[2]; 

這裏調用哪個函數?

+3

對於'const'對象或訪問路徑,'const'函數被調用。否則,調用非const。 'array'可能不是類名的好選擇,因爲在新的C++ 11標準中有一個'std :: array'模板。 – Potatoswatter 2011-04-23 04:45:31

+0

只是一個觀察。如果你從const版本返回const引用會更好。例如,請參閱* std :: vector :: operator [] *的聲明。 – pic11 2011-04-23 10:00:24

回答

2

在第二個示例中,將調用非const版本,因爲不需要轉換,而且不需要轉換的調用比需要轉換的調用更好。

但是,最終你會遇到一個基本問題:你真正想要的是行爲根據你是使用你的對象作爲右值還是左值而改變,而const實際上並沒有這樣做。爲了使它正常工作,通常要返回一個代理對象,超載operator=operator T的代理對象:

template <class T> 
class myarray { 
    T *ptr; 

    class proxy { 
     T &val; 
     proxy &operator=(proxy const &p); // assignment not allowed. 
    public: 
     proxy(T &t) : val(t) {} 
     operator T() const { return val; } 
     proxy &operator=(T const&t) { val = t; return *this; } 
    }; 

    proxy const operator[](int sub) const { return proxy(ptr[sub]); } 
    proxy operator[](int sub) { return proxy(ptr[sub]); } 
    // obviously other stuff like ctors needed. 
}; 

現在,我們得到理智的行爲 - 當/如果我們array<int>(或其他類型)是const,我們的operator[] const將被使用,它會給出一個const proxy。由於其賦值運算符是而不是常量,嘗試使用它們將失敗(不會編譯)。

OTOH,如果原始array<int>不是const的,我們會得到一個非const代理,在這種情況下,我們可以同時使用operator Toperator=,並能夠同時讀取和寫入的array<int>價值。

+0

這與原來的解決方案有相同的問題 - 如果你想要做的話,比如'object [1] .swap(object [2]);',首先,語法將會是錯誤的,因爲'proxy '即使'T'確實沒有定義那個函數,其次,因爲你不返回一個引用,即使'proxy'是非const,你也不需要複製'object [2]'。 – Puppy 2011-04-23 19:29:14

+0

coffin什麼是轉換,你在const版本中討論過 – avinash 2011-04-24 03:42:40

+0

@avinash:從'myarray&'轉換爲'myarray const&'。它可以隱式完成,但仍然不如不進行轉換那麼好。 – 2011-04-24 03:52:03

2

你的const版本應該返回const int&int,使語義只是兩種功能之間的相同

一旦你做完了,它並不重要哪一個被使用。如果const版本必須被使用,因爲你的對象有一個const上下文,那麼它將是...並且不會影響,因爲你不想修改任何東西。否則,它將使用非const版本......但效果相同。

+1

我不同意。我發現返回'const int&'與'int'相比沒有好處。 – fredoverflow 2011-04-23 06:45:47

+0

@FredOverflow:對稱,全是。我不希望能夠修改'const'對象上的operator []'的結果(即使它只是一個副本):這會引起誤解。 – 2011-04-23 16:18:28

+1

您無法修改通過值返回標量的函數的結果。你得到一個*值*,而不是一個臨時對象。 – fredoverflow 2011-04-23 17:32:48

相關問題