Перегрузка и оператор круглых скобок в C++

Я хочу определить класс myVector, который поддерживает оба назначения operator= и доступ к скобкам, например myclass(1) = 0.5, Смотрите пример фиктивного ниже

class myVector
{
public:
    vector<double> _v;
    myVector(unsigned int size) : _v(size, 0) { }

    double& operator()(int i)
    {
        return _v[i];
    }

    unsigned int size() const { return _v.size(); }

    myVector& operator=(const myVector& v)
    {
        _v.resize(v.size());
        for(int i=0;i<v.size();i++)
            _v[i] = v(i);
    }
}

Этот код не может быть скомпилирован, так как () не определяется как постоянная функция. Это потому, что я хочу включить прямое назначение, такое как myvector(1) = 2, Чтобы решить эту проблему, я могу думать только о двух решениях. Одним из них является определение чего-либо. лайк double getValue(int i) const но это кажется странным, так как добавлен некоторый дублирующий код. Другой, чтобы удалить const от подписи () функция, но это также нежелательно. Я уверен, что будет хорошая работа, но я не могу ее найти.

2 ответа

Правильное решение - "оба". Функции-члены, включая операторов, могут быть перегружены на const-несс this указатель фактически является параметром и участвует в разрешении перегрузки).

double& operator()(int i) { return _v[i]; }
double operator()(int i) const { return _v[i]; }

ПРИМЕЧАНИЕ. При использовании операторов, не являющихся членами, левый объект - это не просто параметр, это параметр.

Для конкретного случая оператора () вы должны просто предоставить две перегрузки:

double& operator()( int i ) { return _v[i]; }
double operator()( int i ) const { return _v[i]; } // [1]

Если бы это был шаблонный контейнер, вторая перегрузка вернула бы const&, но учитывая, что это doubleВозврат копии в порядке.

Теперь в качестве рекомендации вы можете реализовать конструктор копирования, а затем реализовать простой swap функция:

void myVector::swap( myVector & lhs ) {
   _v.swap( lhs._v );
}

С этими двумя инструментами, вы можете использовать идиоматическую реализацию operator=:

myVector& myVector::operator=( myVector rhs ) { // by value
   swap( *this, rhs );
   return *this;
}

Другое дело, что не имеет смысла закатывать собственный цикл для копирования векторов, они уже знают, как это сделать самостоятельно, поэтому _v = v._v; имеет тот же эффект, что и ваш цикл.

Другие вопросы по тегам