2010-06-01 10 views
5

Nur neugierig Überlastungen auf, warum ein param ein const in Betrieb sein muss Überlastungwarum muss Ihnen das Schlüsselwort const in Operator

CVector& CVector::operator= (const CVector& param) 
{ 
    x=param.x; 
    y=param.y; 
    return *this; 
} 

konnte nicht Sie einfach so etwas getan haben ??

CVector& CVector::operator= (CVector& param) //no const 
{ 
    x=param.x; 
    y=param.y; 
    return *this; 
} 

Ist das nicht, wenn etwas ein const wird, ist es für den Rest des Lebens Anwendungen unveränderlich ist ?? Wie unterscheidet sich das beim Überladen der Operation ???

Antwort

2

A const Parameter const in der gesamten Funktion ist es verwenden, es ändern außerhalb davon seine Konstantheit nicht.

In diesem Fall möchten Sie ein const-Argument deklarieren, so dass Ihr Zuweisungsoperator sowohl nicht-const-Variablen als auch const-Variablen akzeptiert; Der letztere Fall enthält insbesondere das Ergebnis von Ausdrücken, das eine temporäre const-Variable ist und die Sie generell bei Zuweisungen unterstützen möchten.

+0

O, Sie sagen, dass g = (a + b * c) das Ergebnis auf der rechten Seite gilt als eine Konstante ?? Wenn Sie sagen, dass eine Konstante nur eine Konstante innerhalb der Funktion ist. Willst du sagen, dass diese Funktion ausgeführt wird? Diese Werte können wieder geändert werden ?? – numerical25

+0

Sie wissen was. Es macht jetzt Sinn. Wenn ich einen konstanten Wert in eine Variable umwandle. das macht die Variable nicht zu einem const, es bedeutet nur, dass es jetzt den Wert von const hält, der änderbar sein kann – numerical25

+0

@numerical, bedenke, dass deine Idee nur funktioniert wie das, was du erwähnt hast, wenn es pass-by-reference ist. – YeenFei

8

Sie brauchen nicht konst:

@ numerical25: Einfach nur neugierig, warum ein param ein const in Betrieb sein muss

Überlastung

Es ist nicht erforderlich, aber es ist ein gute Designentscheidung.

Siehe C++ Standard Abschnitt 12,8-9:

Ein benutzer erklärt Kopie Zuordnung Operator X :: Operator = ist eine nicht-statische Nicht-Template-Elementfunktion der Klasse X mit genau einem Parameter des Typs X, X &, const X &, volatil X & oder const flüchtig X &


Ich denke, es ist eine gute Idee, aber:

einen const-Parameter verwenden, funktioniert aber scheint wie eine logische Design-Entscheidung für mich aber, weil Sie sicherstellen wollen, dass der andere Wert wird nicht geändert.

Es erzählt anderen Menschen, die Ihre Klasse verwenden, die Sie nicht den other Wert sich ändern, wenn Sie etwas sagen wie: myObject = other; und es erzwingt dies, so können Sie nicht versehentlich other ändern.

Auch wenn Sie nicht konstante Referenzen auf das Objekt als Parameter zulassen, begrenzen Sie die Anzahl der Objekte, die Ihre Funktion verwenden können. Wenn es const ist, kann es für Parameter verwendet werden, die const und non const sind. Wenn Ihr Parameter nicht const ist, kann er nur von Parametern verwendet werden, die nicht const sind.


const gilt nur für die aktuelle Referenz, nicht das Objekt:

@ numerical25: nicht ist, wenn etwas ein const wird, ist es unveränderlich für den Rest des Lebens-Anwendungen? ? Wie unterscheidet sich das beim Überladen der Operation ???

Eine const Referenz ist einfach, dass eine Referenz, die const ist. Es ändert nicht die Konstante des tatsächlichen Objekts, das Sie übergeben.


Ein Beispiel für nicht-const Operator Überlastung:

Hier ist ein Beispiel der Bediener eine Überlastung in dem die Parameter nicht const ist.
ICH NICHT DIESE ZWAR ZU TUN:

class B 
{ 
public: 
const B& operator=(B& other) 
{ 
    other.x = 3; 
    x = other.x; 
    return *this; 
} 

int x; 
}; 


void main(int argc, char** argv[]) 
{ 
B a; 
a.x = 33; 
B b; 
b.x = 44; 
a = b;//both a and b will be changed 
return 0; 
} 
+2

Und es ist 'const' für den Umfang der Deklaration nicht die Anwendungslebensdauer. – CuppM

+0

@CuppM: Ja, das ist impliziert, da die gesamte Referenzvariable selbst den Gültigkeitsbereich verlässt. Es ändert jedoch nicht die Const-ness des ursprünglichen Objekts während seines Umfangs. Zum Beispiel, wenn Sie 2 Threads haben. –

1

Wenn Sie verwendet

CVector& CVector::operator= (CVector& param) // no const 

dann tat dies:

const CVector& my_vector = GetMyVector(); 
some_other_vector = my_vector; // call assignment operator - error! 

Sie erhalten eine Fehlermeldung erhalten, weil my_vector ein const CVector& ist und das kann nicht zu einem CVector& (nicht-const gegossen werden Referenz). Es ist nur die lokale Referenz darauf in der operator= Funktion, die const ist, nicht das gesamte Objekt selbst.

0

Aus dem gleichen Grund würden Sie const anywhere verwenden: um sicherzustellen, dass zukünftige Änderungen an der Methode den übergebenen Parameter nicht versehentlich ändern, um die Benutzer zu dokumentieren, dass es param ohne Risiko passieren kann Es ändert sich und ermöglicht es Anrufern, Referenzen weiterzuleiten, die im aufrufenden Code als const deklariert sind.

1

Sie können die nicht-const-Variante verwenden, aber dies hat zwei Auswirkungen, eine, die funktional ist, und eine, bei der es darum geht, was Sie als Verfasser der Funktion dem Benutzer sagen.

1) Menschen die Funktion aufrufen, die nicht zu nennen wäre in der Lage es mit einem const-Variable

2), wenn Sie eine Funktion Argument haben, das ist eine nicht konstante Referenz, eine nicht konstante Referenz nimmt Sie sind Signalisierung, "Ich behalte das Recht, dies zu ändern". Wenn ein Benutzer Ihrer Funktion a = b; schreibt, erwartet er normalerweise nicht, dass sich b ändert.

Beachten Sie, dass es eine dritte Option ist man dafür verwenden könnte, Pass-by-Wert:

CVector& CVector::operator= (CVector param) //no reference 

Das habe ich oben erwähnt nicht eine der beiden Probleme haben. Es ist jedoch sehr ineffizient. Wegen dieser drei Faktoren wird das Vorübergehen auf const bevorzugt, insbesondere in Fällen wie einem Vektor, wo das Kopieren teuer sein kann.

0

Ein weiterer Grund ist, um Konvertierungen zu ermöglichen. Zum Beispiel:

string s = "foo"; 
s = "bar"; 

Hier könnte eine Implementierung nur bietet den Zuweisungsoperator wählen, die eine konstante Referenz auf einen String als Parameter übernimmt, und ist abhängig von dem Compiler einen Konstruktor mit einem temporären String aus dem char erstellen * "Bar". Dies würde nicht funktionieren, wenn der Parameter op = nicht const wäre, da Sie eine temporäre nicht an eine nicht konstante Referenz binden können.

0

Das const-Qualifikationsmerkmal macht den übergebenen Parameter (in Ihrem Beispiel ist es 'const CVector & param') schreibgeschützt. Das Qualifikationsmerkmal const stellt sicher, dass der Parameter (param) nicht innerhalb der operator =() -Methode geändert wird.

Ohne die const Qualifier ist folgendes möglich:

CVector& CVector::operator= (CVector& param) 
{ 
    x=param.x; 
    y=param.y; 

    param.x = 10; // some random value 
    param.y = 100; 

    return *this; 
} 

Das obige Verfahren ändert die richtige ‚param‘ Seite Operand nach den Wert auf der linken Seite Operand zugewiesen wird. Das Qualifikationsmerkmal const hilft Ihnen dabei, die Semantik der Zuweisungsoperation nicht zu verletzen.

Verwandte Themen