2016-01-04 1 views
8

У меня есть класс шаблона массив:C++ - перегрузки оператор []

template <class T=int, int SIZE=10> 
class Array { 
    T TheArray[SIZE]; 
public: 
    void Initialize() { 
     for (int idx=0; idx < SIZE; idx++) { 
      TheArray[idx] = T(); 
     } 
    } 

    T& operator [](int idx) { 
     return TheArray[idx]; 
    } 

    T operator [](int idx) const { 
     return TheArray[idx]; 
    } 
} 

У меня есть несколько вопросов, на операторе [] перегрузки (я нашел этот пример на нетто).

Я понимаю, что T& operator [](int idx) возвращает ссылку на значение массива с индексом idx и что T operator [](int idx) const возвращает свое значение. Однако я не уверен, в каком случае ссылка или значение будут возвращены с помощью оператора [].

Также, если я изменю T operator [](int idx) const ->T operator [](int idx), компилятор жалуется. Почему это? Я могу понять, что компилятор жалуется, потому что только тип возврата отличается, но почему он не жалуется, когда добавляется const? Это означает, что не внутренняя часть класса изменяется, не так ли?

Я пытался отладить эту маленькую основную реализацию:

int main() { 
    int val; 
    Array<> intArray; 

    intArray.Initialize(); 
    val = intArray[1]; 
    printf("%d", intArray[1]); 
    intArray[1] = 5; 
} 

И каждый раз, когда T& operator [](int idx) называется. Зачем?

Заранее спасибо.

+0

На стороне примечания, предпочитайте правильные конструкторы для функций типа 'initialize'. C++ дает вам идеальный инструмент для инициализации объектов, и он называется конструктором. – SergeyA

ответ

12

Перегрузка operator[] будет выбрана исходя из const -qualification объекта, на который вы его называете.

Array<> intArray; 
intArray[1]; //calls T& operator[] 

const Array<> constArray; 
constArray[1]; //calls T operator[] 

Если вы удалите const из T operator[], вы получите ошибку, потому что функции-члены не могут иметь одинаковые const -qualification и параметры, как не было бы никакой возможности для выбора между ними.

12

Первое, что касается [] как синтаксический сахар для звонка this->operator[].

версия const будет называться, если this является const указатель, иначе не- const версия будет называться.

Перейдя, вы должны использовать const T& operator [](int idx) const {, то есть иметь версию const, вернув ссылку const. Это позволит сэкономить накладные расходы на получение глубокой копии.

И, наконец, const -ness функции является частью его подписи. Это позволяет перегружать на основе const -ness. В противном случае у вас не могло быть двух версий operator[].

+1

Я бы даже назвал возвращение временным, а не const ссылкой на дизайн-запах/ошибку здесь, поскольку это приводит к несоответствиям, то есть: [почему я не могу использовать аргументы const в memcpy?] (Http://stackoverflow.com/q/ 17669913/1942027). Следует ориентироваться на стандартной библиотеке, чтобы предотвратить неожиданное поведение, и ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector/operator_at) возвращает ссылку на константу , –