2010-04-28 7 views
8

Ich weiß, wenn Sie void function_name schreiben (int & a), dann Funktion wird nicht lokale Kopie der Variablen als Argument übergeben. Auch in der Literatur haben Sie festgestellt, dass Sie void function_name (const int & a) schreiben sollten, um Compiler zu sagen, dass ich nicht möchte, dass die Variable als Argument übergeben wird.Differenz von Funktionsargument als (const int &) und (int & a) in C++

Also meine Frage: Was ist der Unterschied mit diesen beiden Fällen (außer dass "const" dafür sorgt, dass die übergebene Variable nicht durch Funktion verändert wird !!!) ???

+0

Ist es nicht der Unterschied zwischen 'const int & a' und' int a' oder sogar 'const int a' der eigentliche Punkt? Ich frage mich, warum der Compiler zwischen const int & a und const int a unterscheiden sollte? Oder wird mit der Garantie, dass der Compiler keine Kopie macht und "const int a" eine Kopie macht? Wie kannst du sagen "den Compiler wählen lassen"? – kriss

+0

Siehe auch hier: http://StackOverflow.com/Questions/2139224/2139254#2139254 – sbi

+1

@Kriss: Der Compiler kann nicht wählen. Beachten Sie, dass Sie eine Funktion 'void f ( int x);'. Zum Zeitpunkt der Deklaration hat der Compiler keine Informationen darüber, ob Sie das Objekt ändern werden oder nicht. Wenn Sie nur den Code sehen, kann er bestätigen, dass sich der Code nicht ändert oder den Parameter ändert. Und selbst dann, wenn der Code einen Parameter ändert, wie kann der Compiler wissen, ob diese Änderung außerhalb der Funktion sichtbar sein soll? Selbst wenn es mit der Definition entscheiden könnte, wie würde der Compiler die Signatur in Übersetzungseinheiten berücksichtigen, in denen nur der Header enthalten ist? –

Antwort

10

Sie sollten const in der Signatur verwenden, wenn Sie nicht schreiben müssen. Das Hinzufügen von const zu der Signatur hat zwei Auswirkungen: Es teilt dem Compiler mit, dass es überprüft werden soll und garantiert, dass Sie dieses Argument in Ihrer Funktion nicht ändern. Der zweite Effekt besteht darin, dass externer Code Ihre Funktion verwenden kann, indem Objekte übergeben werden, die selbst konstant sind (und Provisorien), wodurch mehr Nutzungen der gleichen Funktion ermöglicht werden.

Gleichzeitig ist das Schlüsselwort const ein wichtiger Teil der Dokumentation Ihrer Funktion/Methode: Die Funktionssignatur sagt explizit, was Sie mit dem Argument vorhaben und ob es sicher ist, ein Objekt zu übergeben ist Teil der Invarianten eines anderen Objekts in Ihre Funktion: Sie sind explizit darin, dass Sie sich nicht mit ihrem Objekt anlegen.

Die Verwendung von const erzwingt eine strengere Reihe von Anforderungen in Ihrem Code (die Funktion): Sie können das Objekt nicht ändern, aber gleichzeitig weniger restriktiv in Ihren Aufrufern, wodurch Ihr Code wiederverwendbar wird.

void printr(int & i) { std::cout << i << std::endl; } 
void printcr(const int & i) { std::cout << i << std::endl; } 
int main() { 
    int x = 10; 
    const int y = 15; 
    printr(x); 
    //printr(y); // passing y as non-const reference discards qualifiers 
    //printr(5); // cannot bind a non-const reference to a temporary 
    printcr(x); printcr(y); printcr(5); // all valid 
} 
7

So my question: what is the difference with this two cases (except that "const" enshures that the variable passes will not be changed by function!!!)???

Das ist der Unterschied.

+0

Ich bin vom Aspekt der Kopie. – Narek

+0

@Narek: Das 'const' hat keinen Einfluss darauf, ob eine Kopie ausgeführt wird oder nicht. Durch den Verweis ("const" oder nicht) wird eine Kopie vermieden. Das Übergeben nach Wert (ohne Verwendung einer Referenz) führt zu einer Kopie, unabhängig davon, ob der Parameter "const" ist oder nicht.Die Verwendung eines "const" -Referenzparameters für ein "int" wird im Allgemeinen als unnötig erachtet, da die Übergabe nach Wert in diesem Fall keine zusätzlichen Kosten verursacht. –

+0

@Michael: und was ist mit 'const int' vs' int'? – kriss

1

Sie sagen den Unterschied richtig. Sie können formulieren es auch als:

Wenn Sie angeben möchten, dass die Funktion für init_to_big_number(int& i)Änderung das Argument (dh kann das Argument (Variable) Referenz durch Angabe Im Zweifelsfall geben Sie es const

..

Beachten Sie, dass der Vorteil des Nichtkopierens des Arguments in der Performance besteht, dh für "teuere" Objekte. Für eingebaute Typen wie int macht es keinen Sinn void f(const int& i) zu schreiben. Das Übergeben der Referenz an die Variable ist genauso teuer wie das Übergeben des Wertes

0

Sie werden für verschiedene Zwecke verwendet es. Durch die Übergabe einer Variablen mit const int& wird sichergestellt, dass Sie die Semantik "Pass-by-Copy" mit einer viel besseren Leistung erhalten. Sie werden garantiert, dass die aufgerufene Funktion (außer wenn sie einige verrückte Dinge unter Verwendung von const_cast ausführt) Ihr übergebenes Argument nicht ändert, ohne eine Kopie zu erstellen. int& wird verwendet, wenn in der Regel mehrere Rückgabewerte von einer Funktion vorhanden sind. In diesem Fall können diese verwendet werden, um die Ergebnisse der Funktion zu halten.

+2

Aber Sie erhalten keine Semantik zum Kopieren von Kopien mit 'const int &'. Äußere Änderungen am übergebenen Objekt werden in der aufgerufenen Funktion sichtbar. Dies ist definitiv keine Kopie der Semantik, es ist eine Eigenschaft von Pass by Reference. –

1

Es gibt einen großen Unterschied ist, dass sie in Bezug auf die Parameter arbeiten könnte, Sagen Sie bitte eine Kopie Konstruktor für die Klasse von int haben,

customeclass(const int & count){ 
    //this constructor is able to create a class from 5, 
    //I mean from RValue as well as from LValue 
} 
customeclass(int & count){ 
    //this constructor is not able to create a class from 5, 
    //I mean only from LValue 
} 

Die const Version im Wesentlichen auf temporäre Werte und nicht konstant arbeiten kann Version konnte nicht auf temporär funktionieren, Sie würden leicht Problem konfrontiert, wenn Sie const, wo es benötigt wird, und verwenden Sie STL, aber Sie bekommen wired Fehler sagen, es konnte die Version nicht finden, die vorübergehend dauert. Ich empfehle const, wo immer Sie können.

0

Ich würde sagen, dass

void cfunction_name(const X& a); 

mir erlaubt, einen Verweis auf temporäres Objekt zu übergeben, wie

X make_X(); 

function_name(make_X()); 

Während

diese
void function_name(X& a); 

nicht erreichen folgt. mit dem folgenden Fehler Fehler: ungültige Initialisierung von nicht-const Referenz des Typs 'X &' von einem temporären Typ 'X'

0

lassen Sie die Leistungsdiskussion, lassen Sie den Code sprechen!

void foo(){ 
    const int i1 = 0; 
    int i2 = 0; 
    i1 = 123; //i gets red -> expression must be a modifiyble value 
    i2 = 123; 
} 
//the following two functions are OK 
void foo(int i) { 
    i = 123; 
} 
void foo(int & i) { 
    i = 123; 
} 
//in the following two functions i gets red 
//already your IDE (VS) knows that i should not be changed 
//and it forces you not to assign a value to i 
//more over you can change the constness of one variable, in different functions 
//in the function where i is defined it could be a variable 
//in another function it could be constant 
void foo(const int i) { 
    i = 123; 
} 
void foo(const int & i) { 
    i = 123; 
} 

mit „const“, wo es benötigt wird, hat folgende Vorteile: * Sie die Konstantheit einer Variablen ändern kann ich in verschiedenen Funktionen in der Funktion, wo i definiert ist es eine Variable könnte in Eine andere Funktion könnte ein konstanter Wert sein. * bereits Ihre IDE weiß, dass ich nicht geändert werden sollte. und es zwingt Sie keinen Wert i

Bezug zuweisen Oops

Verwandte Themen