2017-01-19 2 views
0

ich zur Zeit ein Polynomial -Klasse in C++ zu schreiben, die ein Polynom der Form darstellen sollte:Warum wird der schreibgeschützte Operator [] nicht verwendet?

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

wo a_0, ..., a_i sind alle int ‚s.

Die Klasse verwendet intern eine Elementvariable a_ vom Typ std::vector<int>, um die konstanten Faktoren a_0, ..., a_i zu speichern. Für den Zugriff auf die konstanten Faktoren der operator[] wird in der folgenden Art und Weise überlastet:

lesen und schreiben:

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

Dies wird scheitern, wenn versucht wird einer der Faktoren sich ändern a_i mit:

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

Read-only:

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

    return a_.at(i); 
} 

Die leicht abweichende Implementierung ermöglicht ein recht komfortables Looping über die Faktoren von zwei unterschiedlich großen Polynomen (ohne sich Gedanken über des Grades des Polynoms machen zu müssen).

Leider scheinen ich hier etwas zu verpassen, da die operator+ -overloading (die Verwendung dieses komfortablen read-only macht - operator[]) ausfällt.

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; 
} 

die Mathematik nichts dagegen beteiligt. Der wichtige Punkt ist, dass die i ist immer im Bereich von

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

somit schriftlich res[i] gültig ist. Jedoch versuchen (*this)[k] und other[i-k] von Indizes zu lesen, die nicht unbedingt im Bereich [0, (*this).a_.size() - 1] liegen.

Das sollte in Ordnung sein mit unserer schreibgeschützt -implementierung der operator[] richtig? Ich bekomme immer noch einen Fehler beim Zugriff auf a_ bei ungültigen Indizes. Was könnte der Compiler verursacht die Lese-Schreib- -Implementierung in der Leitung zu verwenden:

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

Besonders der Teil auf der rechten Seite der Gleichung.

Ich bin sicher, dass der Fehler durch die „falsche“ Verwendung des Lese- und Schreib verursacht wird - operator[].Denn mit einer zusätzlichen Prüfung fixiert den ungültigen Zugriff:

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

Was soll ich mit der Verwendung des operator[] -overloading fehlt? Warum wird nicht schreibgeschützt - operator[] hier verwendet?

+1

Der binäre 'operator *' sollte normalerweise 'const' sein. – molbdnilo

+1

Es ist kontraintuitiv und verwirrend, '' verschiedene Dinge zu tun. Der Programmierer erwartet dasselbe Verhalten. – PaulMcKenzie

+0

Bevorzugen Sie einen Nicht-Glied 'Polynomoperator * (Polynom const & lhs, Polynomial const & rhs)', da Sie keinen privilegierten Zugriff auf 'this' benötigen. Und ja, "at" wäre besser als ein magisches '[]', das manchmal das tut, was Sie wollen ... – Useless

Antwort

6

(*this)[k] verwendet die nicht-const this als die Funktion enthält es nicht const.

Daher wird die non-const Überladung von [] vom Compiler bevorzugt.

Sie könnten dies mit einem hässlichen const_cast umgehen, aber wirklich sollten Sie das Verhalten der beiden Versionen des [] Betreibers so ähnlich wie möglich zu halten. Außerdem besteht die std::vector Überladung von [] nicht darauf, dass der Index Grenzen überprüft, im Gegensatz zu at, die sein müssen. Ihr Code ist eine Abweichung davon und könnte daher Leser Ihres Codes verwirren.

+0

Vielen Dank. Tatsächlich ist die Überladung von operator * 'const', daher ist keine' const_cast' notwendig. Ich werde die Antwort so schnell wie möglich annehmen. – Herickson

Verwandte Themen