2015-10-21 105 views
2

看一看多個操作符[]重載

class Array { 
    const unsigned int _size; 
    int _array[100]; 

public: 
    Array() : _size(100) { 
     for(unsigned int i = 0; i < _size; i++) 
      _array[i] = 0; 
    } 

    int& operator[](unsigned int index) { 
     cout << "normal operator[].\n"; 
     return _array[index]; 
    } 

    const int& operator[](unsigned int index) const { 
     cout << "const operator[].\n"; 
     return _array[index]; 
    } 
}; 

int main() 
{ 
    Array a; 

    a[3] = 1; 
    cout << a[3] << "\n"; 

    system("pause"); 
    return 0; 
} 

「正常操作符[]」行被執行兩次這個簡單的數組類,雖然我期望第二呼叫(cout << a[3] << "\n";)使用const是重載操作符的版本,因爲它不會更改數組本身。

這是爲什麼?有沒有辦法強制const的版本被調用,因爲我希望?

+1

'a'在該表達式中不是'const',所以不會調用const超載。如果你想強制它,你可以使用'const_cast (a)[3]'但它確實沒有必要。 – user657267

+0

那有什麼意義?我試圖模仿std :: vector,因爲它也有兩個重載的operator []函數。你是說,除非std :: vector對象是const(因爲我沒有看到這一點),非const版本將永遠被調用? – Pilpel

+3

'除非std :: vector對象是const,否則總是會調用非const的版本'這是(有點)const const超載的定義,是的。請注意,底層對象本身可能是非const的,並且通過const引用來訪問,通常情況下是這樣。在你的代碼中,你可以使用'Array const&b = a; cout << b [3];' – user657267

回答

1

當你有一個方法的const重載版本時,const對象是const時會被調用。例如:

#include <iostream> 
using namespace std; 

class MyClass 
{ 
public: 

    void foo() 
    { 
     cout << "foo()" << endl; 
    } 

    void foo() const 
    { 
     cout << "foo() const" << endl; 
    } 
}; 

int main() 
{ 
    MyClass a; 
    const MyClass b; 

    a.foo(); 
    b.foo(); 

    return 0; 
} 

會調用該對象a,並且const版本的對象b正常foo()

在你的情況,你只需要避免試圖分配到const版本。例如:

Array a; 
const Array b; 

a[3] = 1; 
// b[3] = 1; // error 
cout << a[3] << "\n"; 
cout << b[3] << "\n"; 

工作正常。但是,如果您嘗試將作業設置爲b,則會出現編譯錯誤。

0

std::ostream &operator<<(int x)沒有將其參數設置爲const(因爲在傳遞值時const不起作用),所以可以調用非const operator[]

那麼,什麼時候會調用const operator[]

確實,const vector變量聲明幾乎總是在一些邊緣情況下無用。主要原因const operator[]很重要,並且最常見的是你會看到它被使用,將它稱爲參考參數。

int readStuff(const std::vector<int> &dontMutateMe) { 
    return dontMutateMe[42]; // const 
} 

Constant reference parameters are valuable,並且該代碼不是沒有const operator[]工作。

+0

'std :: ostream&operator <<'的參數聲明與爲'a'選擇的重載無關,如果聲明爲'int',非''constst'運算符[]'仍然會被調用const&x'。 – user657267