2010-10-11 18 views
11

Sollte ich immer eine Std :: String durch const Verweis auf eine Funktion übergeben, wenn alles, was innerhalb dieser Funktion getan wird, ist, diese Zeichenfolge zu kopieren? Was ist der Unterschied (perf oder anders) zwischen der Übergabe nach Wert und der Weitergabe als Referenz? Wie ich es verstehe, benutzt man operator= und den anderen Kopierkonstruktor. Ist das der Fall?Wie sollte ich eine Std :: String an eine Funktion übergeben?

+3

Wenn Sie als Referenz übergeben werden, wird keine Kopie erstellt. Wenn Sie den Wert übergeben, wird der Kopierkonstruktor verwendet. – Anycorn

Antwort

19

Sollte ich immer eine std :: string durch const Verweis auf eine Funktion übergeben, wenn alles, was innerhalb dieser Funktion getan wird, ist, diese Zeichenfolge zu kopieren?

Nein. Wenn Sie nur die Zeichenfolge innerhalb der Funktion kopieren, sollten Sie nach Wert übergeben. Dies ermöglicht dem Compiler mehrere Optimierungen durchzuführen. Für mehr lesen Sie Dave Abrahams "Want Speed? Pass by Value."

Was ist der Unterschied (perf oder anders) zwischen der Weitergabe von Wert und der Weitergabe durch Referenz? Soweit ich weiß, benutzt man operator = und den anderen Copy-Konstruktor. Ist das der Fall?

Nein, das ist überhaupt nicht der Fall. Eine Referenz ist kein Objekt; es ist eine Referenz auf ein Objekt. Wenn Sie den Wert übergeben, wird eine Kopie des übergebenen Objekts erstellt. Wenn Sie als Referenz übergeben werden, wird ein Verweis auf das vorhandene Objekt erstellt, und es gibt keine Kopie. A good introductory C++ book wird diese grundlegenden Konzepte im Detail erklären. Es ist wichtig, die Grundlagen zu verstehen, wenn Sie Software in C++ entwickeln möchten.

+0

Ich denke, es hängt davon ab, was er meint, indem man eine Kopie macht. Wenn es sich beispielsweise um ein Mitglied handelt, sollte es als Referenz übergeben und einfach in das Mitglied kopiert werden. In C++ 0x tun Sie es nach Wert und 'std :: move' es in das Mitglied. – GManNickG

+0

Anstelle von std :: move könnten Sie die swap-Methode (oder std :: swap) verwenden, um ein ähnliches Verhalten zu erhalten, wenn Sie C++ 0x nicht verwenden können – Grizzly

+0

Gibt es eine Kombination aus Compiler und Beispiel Code, bei dem die Wertübergabe tatsächlich besser ist? Ich würde gerne wissen. –

27

Glauben Sie nicht alles, was Sie im Internet lesen. Es ist besser const Referenz zu übergeben. Geben Beweis, schrieb ich ein Testprogramm ...

test.cpp:

#include <ctime> 
#include <iostream> 
#include <string> 

void foo(std::string s); 
void bar(const std::string& s); 

int main() { 
    const std::string s("test string"); 

    clock_t start = clock(); 
    for (int it = 0; it < 1000000; ++it) 
     foo(s); 
    std::cout << "foo took " << (clock() - start) << " cycles" << std::endl; 

    start = clock(); 
    for (int it = 0; it < 1000000; ++it) 
     bar(s); 
    std::cout << "bar took " << (clock() - start) << " cycles" << std::endl; 
} 

aux.cpp:

#include <string> 
std::string mystring; 

void foo(std::string s) { mystring = s; } 
void bar(const std::string& s) { mystring = s; } 

Zusammengestellt mit ‚g ++ O3 test.cpp aux.cpp 'und bekam den Ausdruck:

foo took 93044 cycles 
bar took 10245 cycles 

Das Überschreiten der Referenz ist um eine Größenordnung schneller.

+0

Danke, ich werde es selbst ausprobieren :) – nakiya

+1

In Visual Studio 2012: "foo nahm 3701 Zyklen bar dauerte 1110 Zyklen" – nergeia

+0

Mit g ++ 4.8.1 auf x86_64 bekomme ich 4130 vs 1820. Die Lücke schließt. –

Verwandte Themen