Frage zu Funktionsobjekten
-
Hier wurde ja schon erklärt. Zum besseren Nachvollziehen ergänzt du am besten deine Ausgabe-Klasse um (wie schon von @Swordfish angedeutet):
class ausgabe { public: // deine bisherigen Funktionen hier ausgabe(const ausgabe&) { cout << "Kopierkonstruktor!!" << endl; } };
Dann damit ausprobieren.
Und dann implementierst du noch den Move-Konstruktor:
ausgabe(ausgabe&&) { cout << "Move-Konstruktor!!" << endl; }
Und schaust erneut, was passiert.
-
Weil es neben dem Standardkonstruktor auch noch den Kopierkonstruktor (copy constructor) gibt:
ausgabe(const ausgabe &other) { cout << "Kopierkonstruktor!!" << endl; }
Edit: Ups, hatte die anderen Antworten nicht gelesen (manchmal springt er nicht zum letzten Beitrag...).
-
@hustbaer sagte in Frage zu Funktionsobjekten:
Ergänzung: In einem optimierten Build wird der Dtor nur 2x aufgerufen. Dabei wird das Temporary beim Funktionsaufruf weggelassen, der Parameter wird direkt konstruiert.
Ja, und dann noch zusätzlich zu Copy-Elison die RVO. Kopfschmerzen.
-
@Swordfish Naja ge-returnte Parameter können nicht ge-NRVOt werden
Weiss nicht ob der Standard es theoretisch erlauben würde, aber auf Grund der Calling-Conventions kann das im non-inline Fall schonmal gar nicht hinhauen.
Wobei es im Inline Fall interessant wäre ob's theoretisch erlaubt ist.
-
@hustbaer Ich hab' ja gesagt
@Swordfish sagte in Frage zu Funktionsobjekten:
Kopfschmerzen.
@hustbaer sagte in Frage zu Funktionsobjekten:
ge-NRVOt
Den Ausdruck merk' ich mir weil so furchtbar elogant ;p
@hustbaer sagte in Frage zu Funktionsobjekten:
Wobei es im Inline Fall interessant wäre ob's theoretisch erlaubt ist.
Natürlich? Solange as-if ... ?
-
@Swordfish sagte in Frage zu Funktionsobjekten:
@hustbaer sagte in Frage zu Funktionsobjekten:
Wobei es im Inline Fall interessant wäre ob's theoretisch erlaubt ist.
Natürlich? Solange as-if ... ?
Nö ich mein schon den beobachtbaren Teil. Bei (N)RVO ist ja erlaubt dass wirklich die beobachtbaren Effekte der Kopie wegfallen. Sonst wäre es ja uninteressant, z.B. schonmal da AFAIK die meisten Compiler Speicheranforderungen als beobachtbar einstufen (bin mir auch nichtmal sicher ob es vom Standard her überhaupt schon erlaubt wäre Speicheranforderungen wegzuoptimieren).
Also egal was der Standard dazu sagt, es scheint kein aktueller Compiler mit nur einem Dtor-Aufruf zu machen: https://godbolt.org/z/JgWJ__
-
@hustbaer Schönes Beispiel. Ich habe grad keine Lust den Standart danach abzugrasen.
-
Huiiiii, Clang optimiert new+delete weg: https://godbolt.org/z/HyhyHH
Aber leider (noch?) nichtstd::allocator
Aufrufe
-
@hustbaer sagte in Frage zu Funktionsobjekten:
Aber leider (noch?) nicht std::allocator Aufrufe
Naja, die könnten doch auch side-effects haben?
-
@Swordfish Konstruktoren können auch Nebeneffekte haben. So wie auch selbst definierte globale
operator new/delete
Nebeneffekte haben könnten. Trotzdem dürfen die wohl wegoptimiert werden. (Konstruktoren sicher siehe (N)RVO & Co., und bei den globalenoperator new/delete
ist zumindest Clang der Meinung dass es schon OK wäre die Aufrufe wegzuoptimieren.)
Und warum dann nicht auchstd::allocator
?
-
@hustbaer sagte in Frage zu Funktionsobjekten:
@Swordfish Konstruktoren können auch Nebeneffekte haben. So wie auch selbst definierte globale
operator new/delete
Nebeneffekte haben könnten. Trotzdem dürfen die wohl wegoptimiert werden. (Konstruktoren sicher siehe (N)RVO & Co., und bei den globalenoperator new/delete
ist zumindest Clang der Meinung dass es schon OK wäre die Aufrufe wegzuoptimieren.)
Und warum dann nicht auchstd::allocator
?Habe ich nicht gesagt Kopfschmerzen?? Ich denke darüber heute sicher nicht mehr nach.
@hustbaer sagte in Frage zu Funktionsobjekten:
bei den globalen operator new/delete ist zumindest Clang der Meinung dass es schon OK wäre die Aufrufe wegzuoptimieren.
Definier' sie mal selbst, ist clang dann immer noch derselben Meinung?