2017-01-19 22 views
0

В настоящее время я пишу Polynomial -класса в C++, который должен представлять собой многочлен следующего вида:Почему используемый только для чтения оператор [] не используется?

p(x) = a_0 + a_1*x^1 + a_2*x^2 + ... + a_i*x^i 

где a_0, ..., a_i все int «s.

Класс внутренне использует переменную-член a_ типа std::vector<int> для хранения постоянных факторов a_0, ..., a_i. Чтобы получить доступ к постоянная факторам operator[] перегружен следующим образом:

читать и писать:

int &operator[](int i) 
{ 
    return a_.at(i); 
} 

Это сбой при попытке изменить один из факторов a_i с:

i > degree of polynomial = a_.size() - 1 

Только для чтения:

int operator[](int i) const 
{ 
    if (i > this->degree()) { 
    return 0; 
    } 

    return a_.at(i); 
} 

Немножко различная реализация позволяет довольно комфортно зацикливаться на множителях двух разных полиномов (не беспокоясь о степени полинома).

К сожалению, я, кажется, пропустить что-то здесь, так как operator+ -overloading (что делает использование этой удобной только для чтения - operator[]) терпит неудачу.

operator+ -overloading:

Polynomial operator*(const Polynomial &other) { 
    Polynomial res(this->degree() + other.degree()); 

    for (int i = 0; i <= res.degree(); ++i) { 
    for (int k = 0; k <= i; ++k) { 
     res[i] += (*this)[k] * other[i-k]; 
    } 
    } 

    return res; 
} 

Не против математику участие. Важным моментом является то, что i всегда находится в диапазоне

0 <= i < res.a_.size() 

таким образом, чтобы писать res[i] является действительным. Однако (*this)[k] и other[i-k] пытаются читать по индексам, которые не обязательно лежат в диапазоне [0, (*this).a_.size() - 1].

Это должно быть хорошо с нашими только для чтения -обновление operator[] право? Я по-прежнему получаю сообщение об ошибке, которое пытается получить доступ к a_ по недопустимым индексам. Что может заставить компилятор использовать чтения-записи -внедрение в строке:

res[i] += (*this)[k] * other[i-k]; 

Особенно часть на правой стороне равенства.

Я уверен, ошибка вызвана «неправильным» Использование чтения и записи - operator[].Потому что с дополнительной проверкой фиксирует недопустимый доступ:

if (k <= this->degree() && i-k <= other.degree()) { 
    res[i] += (*this)[k] * other[i-k]; 
} 

Что я отсутствующий с использованием operator[] -overloading? Почему нет только для чтения - operator[] здесь используется?

+1

Бинарный 'operator *' обычно должен быть 'const'. – molbdnilo

+1

Это противоречит интуиции и запутывает, что '[]' выполняет разные вещи. Программист ожидает такого же поведения. – PaulMcKenzie

+0

Предпочитайте несимвольный 'Полиномиальный оператор * (Полиномиальный const & lhs, Polynomial const & rhs)', поскольку вам не нужен привилегированный доступ к 'this'. И да, 'at' будет лучше, чем волшебный' [] ', который иногда делает то, что вы хотите ... – Useless

ответ

6

(*this)[k] использует неконстантный this, так как функция не содержит const.

Следовательно, компилятор предпочитает неконстантную перегрузку [].

Вы можете обойти это с помощью уродливого const_cast, но на самом деле вам следует соблюдать поведение двух версий оператора [] как можно более похоже. Кроме того, перегрузка std::vector[] не настаивает на проверке границ индекса, а не на at, которая должна быть. Ваш код является отклонением от этого и, следовательно, может запутать читателей вашего кода.

+0

Спасибо, что очень много. На самом деле '' '' '' '' '' перегрузки '' const', поэтому 'const_cast' не требуется. Я отвечу как можно скорее. – Herickson

 Смежные вопросы

  • Нет связанных вопросов^_^