Heim  >  Artikel  >  Backend-Entwicklung  >  Warum ruft std::thread den Kopierkonstruktor auf, auch wenn er als Referenz übergeben wird?

Warum ruft std::thread den Kopierkonstruktor auf, auch wenn er als Referenz übergeben wird?

Linda Hamilton
Linda HamiltonOriginal
2024-11-16 15:22:03137Durchsuche

Why Does std::thread Call the Copy Constructor Even When Passing by Reference?

std::thread ruft den Kopierkonstruktor auf, wenn er als Referenz übergeben wird

Die Übergabe von Daten an einen Thread mithilfe von std::thread kann insbesondere problematisch sein beim Umgang mit Klassen, die Kopierkonstruktoren deaktiviert haben. Dieses Verhalten ist auf die Tatsache zurückzuführen, dass std::thread seine Argumente nach Wert annimmt.

Betrachten Sie die folgende Klasse Log mit einem deaktivierten Kopierkonstruktor:

class Log
{
public:
    Log(const char filename[], const bool outputToConsole = false);
    virtual ~Log(void);

    // ...

private:
    // Disable copy constructor and assignment operator
    Log(const Log &);
    Log &operator=(const Log &);
};

In der Hauptfunktion, dem Log Der Objektlogger wird als Referenz an die Serverfunktion übergeben:

Log logger("ServerLog.txt", true);
server(ioService, portNumber, logger);

Die Serverfunktion erstellt dann einen neuen Thread mit Logger als Argument:

std::thread newThread(session, &sock, logger);

Dies führt jedoch zu einem Compilerfehler aufgrund des deaktivierten Kopierkonstruktors in Log.

Warum ruft die Übergabe per Referenz den Kopierkonstruktor auf?

Entgegen der allgemeinen Annahme verhindert die Übergabe per Referenz in C nicht der Aufruf des Kopierkonstruktors. Beim Übergeben einer Referenz erstellt der Compiler eine temporäre Kopie des referenzierten Objekts und übergibt sie an die Funktion. Dies liegt daran, dass std::thread erwartet, dass seine Argumente kopierbar sind.

Lösung: Verwendung von std::reference_wrapper

Um in diesem Szenario eine Referenzsemantik zu erreichen, können Sie verwenden std::reference_wrapper:

std::thread newThread(session, &sock, std::ref(logger));

std::ref umschließt eine Referenz so, dass sie für std::thread als kopierbares Objekt erscheint. Sie müssen jedoch sicherstellen, dass die Lebensdauer des zugrunde liegenden Objekts (in diesem Fall des Loggers) über die Lebensdauer des Threads hinausgeht.

Das obige ist der detaillierte Inhalt vonWarum ruft std::thread den Kopierkonstruktor auf, auch wenn er als Referenz übergeben wird?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn