Перегрузка и оператор круглых скобок в 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;
имеет тот же эффект, что и ваш цикл.