Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

06.03.2014, 01:28

[c++] vector::emplace_back() ruft Copy-Konstruktor auf?

Hallo,
hier steht ja, dass vector::emplace_back() ein neues Objekt konstruiert und an das Ende des Vektors anfügt.
Also den Copy-Konstruktor der einzufügenden Klasse nicht aufruft.

Wenn ich aber diesen Code compiliere, wird ein Fehler ausgelöst :cursing: .

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class NC
{
public:
    NC()
    { }

private:
    NC( const NC& )
    { };
};


int main()
{
    std::vector<NC> vec;
    vec.emplace_back();
}


Quellcode

1
error C2248: "NC::NC": Kein Zugriff auf private Member, dessen Deklaration in der NC-Klasse erfolgte.   d:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0


Wiso wird hier versucht den Copy-Konstruktor aufgerufen?
Kann es sein, dass VS2013 das noch nicht unterstützt?

Mfg
Maxomann

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Maxomann« (06.03.2014, 01:34)


buggypixels

Treue Seele

Beiträge: 125

Wohnort: Meerbusch

Beruf: Programmierer

  • Private Nachricht senden

2

06.03.2014, 08:52

Wie soll denn sonst ein neues Objekt generiert werden?
In der Beschreibung "no copy or move operations are performed" bezieht sich das auf den Vector und nicht das Objekt.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

06.03.2014, 11:05

In der Beschreibung "no copy or move operations are performed" bezieht sich das auf den Vector und nicht das Objekt.
Quatsch. Genau dafür ist emplace_back nämlich gedacht:
"Appends a new element to the end of the container. The element is constructed in-place, i.e. no copy or move operations are performed. "
Das bezieht sich sehrwohl auf das konstruierte Objekt. Dieses wird direkt im Vektor erstellt und erfordert keinen copy- oder move-Konstruktor.

Die Klasse MUSS aber einen Copy-Constructor besitzen, da vector auch eine push/back Methode besitzt, welche den Copy-Constructor verwenden. Im obigen Beispiel wird der Copy-Constructor zwar nicht gerufen, aber public muss er dennoch sein, damit der Rest der vector-Klasse kompiliert werden kann.

Weiterführend:
http://en.cppreference.com/w/cpp/contain…or/emplace_back
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (06.03.2014, 11:10)


Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

4

06.03.2014, 12:26

Zitat von »BlueCobold«

Die Klasse MUSS aber einen Copy-Constructor besitzen

Nein, es reicht ein Move-Konstruktor.
Der Copy-Konstruktor ist nicht notwendig.

Dementsprechend...

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class NC
{
public:
    NC()
    { }
    NC( NC&& )
    { };
private:
    NC( const NC& )
    { };
};


int main()
{
    std::vector<NC> vec;
    vec.emplace_back();
}


Man kann zu diesem Zweck auch den Move-Konstruktor auf default setzen.
Bei längeren Klassen macht das auch Sinn.

Der Move-Konstruktor ist notwendig, weil die Objekte möglicherweise in einen größeren Speicherplatz verschoben werden müssen, wenn der "Vector" wächst.
Wenn ein Kopierkonstruktor notwendig wäre, könnte man keine Smart-Pointer in einem "Vector" platzieren.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

06.03.2014, 13:03

Das Problem ist, dass NC keinen Move Constructor hat. emplace_back() fügt ein Element in den vector ein, was potentiell dazu führt, dass ein neuer Speicherbereich für den vector allokiert werden muss. Das neue Element wird zwar direkt im vector konstruiert, aber alle alten Elemente müssen evtl. verschoben bzw. kopiert werden... ;)

buggypixels

Treue Seele

Beiträge: 125

Wohnort: Meerbusch

Beruf: Programmierer

  • Private Nachricht senden

6

06.03.2014, 15:03

Also die Kollegen verwenden etwas andere Worte:
http://www.cplusplus.com/reference/vecto…r/emplace_back/

Das "copy or move" bezieht sich natürlich auf den Vector und beschreibt ja, wie das neue Objekte eingefügt wird.

Ist aber egal. Die eigentliche Frage ist ja geklärt.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

07.03.2014, 06:36

Das "copy or move" bezieht sich natürlich auf den Vector
Das macht gar keinen Sinn. Weder emplace, noch push rufen eine copy oder move Operation auf dem Vektor auf, sondern nur auf Elementen im Vektor. Den Vektor kann der Entwickler ohnehin nicht beeinflussen, sondern nur die Klasse der Elemente, die er rein steckt.

Nein, es reicht ein Move-Konstruktor.
Der Copy-Konstruktor ist nicht notwendig.
Mea culpa. So stimmt's natürlich. Ich hänge manchmal noch "in alten Zeiten" :rolleyes:
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

8

07.03.2014, 11:41

Wenn Du sowas hier machst:

C-/C++-Quelltext

1
2
Dingens d( param, param);
sammlung.emplace_back( d);

wird trotzdem der Copy Constructor aufgerufen. Die Parameterliste ist ein Dingens, also wird nach einem Konstruktor gesucht, der ein Dingens nimmt. Und das ist der Kopierkonstruktor. Das könnte man vermeiden, indem man std::move() anwendet oder das Objekt direkt im emplace_back() instanziiert.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

9

10.03.2014, 17:49

Danke für die vielen hilfreichen Antworten.

Werbeanzeige