Мой вопрос о разнице между:
const T& operator[](const int nIndex) const;
а также:
T& operator[](const int nIndex);
Зачем мне их обоих определять в классе, какова цель? Разве последнего не будет достаточно?
Объявление функции-члена с const
в конце он позволяет вызывать эту функцию даже на const
объект. Это имеет смысл только для функций-членов, которые не изменяют состояние объекта.
Допустим, у вас есть класс, который перегружает эти операторы, называется X
, Предположительно он ведет себя немного как контейнер, предоставляя доступ к элементам, которые он содержит operator[]
,
Теперь предположим, что пользователь хочет использовать const X
:
const X x = /* fill it */;
use(x[0]);
Должен ли пользователь иметь возможность делать это? Наверное. Если они хотят контейнер, который является неизменным, тогда позвольте им иметь это. Если вы не предоставили const
версия operator[]
они не смогут этого сделать. В конце концов, они не пытаются модифицировать контейнер, а просто смотрят на его содержимое.
Теперь зачем делать const
версия operator[]
вернуть const
ссылка? Потому что это должно. Он возвращает ссылку на члена самого класса. Если контейнер был const
и вернул неconst
Для справки, вызывающая сторона сможет изменять свои внутренние компоненты, просто используя этот оператор:
const X x = /* fill it */;
x[0].modify();
О дорогой, мы меняем состояние x
хотя это const
, Это было бы плохо, и на самом деле, компилятор даже не позволит вам сделать это.
Это функции-члены класса, и версия будет выбрана в зависимости от того, используется ли этот класс как const
контекст.
Эта версия будет называться, когда []
используется на объекте в const
контекст. Это сохраняет const
правильность возвращаемого элемента.
const T& operator[](const int nIndex) const;
Эта версия будет называться, когда []
используется наconst
объект. Это указывает, что когда ваш объект не const
, вы получите элемент, который вы можете изменить, разрешив такой код myObject[0] = 10;
T& operator[](const int nIndex);
Если объект, к которому вы обращаетесь, const
Вы не хотите иметь возможность изменить его. Компилятор не позволит вам вызвать неconst
версия функции.
const vector<int> mints;
mints[3] = 5; // not allowed by compiler
Первый
const T& оператор [] (const int nIndex) const;
является константным методом (функцией), т. е. он гарантирует, что он не изменит какую-либо переменную члена класса (если только она не изменяемая).
Он также возвращает константный объект, что означает, что вы можете вызывать только постоянную функцию, т.е. вы можете вызывать только те функции, которые имеют const в конце, аналогичном приведенному выше.
T& оператор [] (const int nIndex);
Этот метод может изменять переменные-члены и возвращает объект, который может вызывать любые методы класса.
Они нужны нам обоим, потому что постоянный объект будет использовать постоянный метод, а неконстантный будет использовать другой.