перегруженная const функция operator [] и ее вызов - PullRequest
4 голосов
/ 23 апреля 2011

Я определяю две версии перегруженной функции operator[] в классе array.ptr - указатель на первый элемент объекта array.

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

и

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

Теперь, если я определю объект const integer1, вторая функция можетвызываться только ..... но если я создаю неконстантный объект и затем вызываю, как показано ниже:

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

какая функция вызывается здесь?

Ответы [ 2 ]

2 голосов
/ 23 апреля 2011

Во втором примере будет вызвана неконстантная версия, потому что преобразование не требуется, и вызов, не требующий преобразования, является лучшим соответствием, чем вызов, требующий преобразования.

В конечном счете, однако, у вас есть основная проблема: то, что вам действительно нужно, - это поведение, которое меняется в зависимости от того, используете ли вы свой объект в качестве значения или значения, а 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> (или любой другой тип) является константным, будет использоваться наш operator[] const, и он даст const proxy. Поскольку его операторы присваивания не const, попытка их использования не удастся (не скомпилируется).

OTOH, если исходный array<int> не был константным, мы получим неконстантный прокси-сервер, и в этом случае мы можем использовать как operator T, так и operator=, и иметь возможность как читать, так и записывать значение в array<int>.

2 голосов
/ 23 апреля 2011

Ваша константная версия должна возвращать const int&, а не int, так что семантика точно такая же между двумя функциями.

Как только вы это сделаете, она не имеет значения , какой из них используется.Если нужно использовать версию const, потому что ваш объект имеет константный контекст, тогда это будет ... и это не будет иметь значения, поскольку вы не пытаетесь что-либо изменить.В противном случае он будет использовать не const версию ... но с тем же эффектом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...