Оператор [] С++ Get/Set
У меня возникают проблемы с указанием разницы между get и set для оператора []. Мне нужно сказать разницу между этими вызовами функций.
cout << data[5];
data[5] = 1;
Я искал его, и ответы, которые я нашел, все равно не помогли. Люди предлагали сделать подписи для разных методов, добавив const. Я сделал это, и оба они оба назвали один и тот же метод.
Существуют подписи, которые я использовал:
const T& operator[](unsigned int index) const;
T& operator[](unsigned int index);
Что я делаю неправильно?
Ответы
Ответ 1
Решение заключается в использовании объекта "прокси", который задерживает действительную операцию:
#include <vector>
#include <iostream>
template<typename T>
struct MyArray {
std::vector<T> data;
MyArray(int size) : data(size) {}
struct Deref {
MyArray& a;
int index;
Deref(MyArray& a, int index) : a(a), index(index) {}
operator T() {
std::cout << "reading\n"; return a.data[index];
}
T& operator=(const T& other) {
std::cout << "writing\n"; return a.data[index] = other;
}
};
Deref operator[](int index) {
return Deref(*this, index);
}
};
int main(int argc, const char *argv[]) {
MyArray<int> foo(3);
foo[1] = 42;
std::cout << "Value is " << foo[1] << "\n";
return 0;
}
Простая const
-ness не может использоваться, потому что вам может потребоваться прочитать из неконстантного экземпляра, то есть причина, по которой вы должны задержать операцию: присваивание происходит "после" доступа, а компилятор не работает " t скажите, будет ли доступ позже использоваться как цель для назначения или нет.
Идея заключается в том, что при доступе вы просто храните запрошенный индекс и ждете, чтобы узнать, происходит ли операция чтения или записи. Предоставляя оператор неявного преобразования из прокси-сервера в T
, вы знаете, когда выполняется операция чтения, предоставляя и присваивая оператор прокси от T
, который вы знаете при записи.
Ответ 2
Версия const
означает, что если объект, на который он вызывается, является const
, вам разрешено вызывать эту версию оператора []
и только ту версию.
Но если объект не является const
, тогда можно вызвать обе версии оператора []
, но компилятор выберет неконстантную версию. Другими словами, для неконстантного объекта неконстантная версия оператора может действовать как "сеттер" или "геттер". Вот почему одна и та же версия вызывается в обоих случаях в вашем примере, потому что ваш объект data
не const.
Вам нужно было бы сделать что-то вроде этого:
const Data& data_cref = data;
cout << data_cref[5]; // calls the const version of operator[]
Data& data_ref = data;
data_ref[5] = 1; // calls the non-const version of operator[]
Ответ 3
Чтобы быть совместимым с обычным значением индекса, оператор индекса обычно возвращает ссылку на элемент, который извлекается. Вернув ссылку, индекс можно использовать с обеих сторон задания.
Следовательно, обычно также полезно определить как константные, так и неконстовые версии этого оператора. При применении к объекту индекс должен возвращать ссылку на const, чтобы он присваивал возвращаемому объекту.
---- С++ Primer, пятое издание
Ответ 4
const
версия вашего operator[]
будет вызвана для объекта данных const
:
const Data data;
cout << data[5];