Konstruktor im Konstruktor aufrufen und Frage zu placement new
-
Problem Nummer 1: Warum gibt Visual C++ 2008 hier diesen Fehler aus? Kann man sowas nicht machen?
template <class T> class vector { public: vector(const T *arr, size_t count) //... { //... } vector(const vector &other) : vector(other.data(), other.size()) //C2614: Unzulässige Elementinitialisierung: 'vector<int>' ist weder Basis noch Element { } };Die zweite Sache:
Darf man das machen? Oder ist das bloß schlechter Stil? Oder etwa ganz normal?template <class T> void function() { char *mem = new char[sizeof(T)]; new (mem) T(); char *mem_two = new char[sizeof(T)]; memcpy(mem_two, mem, sizeof(T)); //bezogen auf diese Zeile T &object = *reinterpret_cast<T*>(mem_two): object.~T(); delete[] mem; delete[] mem_two; }
-
1. nein, das wird erst mit dem nächsten standard gehen, das ein construktor einen anderen aufruft.
üblicherweise gibts für das problem aber eh assign:
vector(const vector& rhs) { assign(rhs.begin(), rhs.end()); }memcpy(mem_two, mem, sizeof(T)); //bezogen auf diese Zeile
Nö. memcpy darf man nur auf PODs anwenden...
Also so bald T kein POD ist, hast du undefiniertes Verhalten...dafür gibt es
std::uninitialized_filloder so was in der Richtung
der rest ist ok - aber so was solltest du nur mit gutem grund verzapfen
bb
-
unskilled schrieb:
memcpy(mem_two, mem, sizeof(T)); //bezogen auf diese Zeile
Nö. memcpy darf man nur auf PODs anwenden...
Also so bald T kein POD ist, hast du undefiniertes Verhalten...dafür gibt es
std::uninitialized_filloder so was in der Richtung
der rest ist ok - aber so was solltest du nur mit gutem grund verzapfen
Aber wenn T keine abstrusen Nebeneffekte hat (wie zum Beispiel seine eigene Adresse merken) dürfte das keine Probleme verursachen.
Der Grund dafür ist übrigens eine eigene Version von std::vector, die möglichst schnell sein soll und deshalb solche Sachen macht.
-
TyRoXx schrieb:
Problem Nummer 1: Warum gibt Visual C++ 2008 hier diesen Fehler aus? Kann man sowas nicht machen?
Nein -- noch nicht. Das nennt sich glaub'ich Konstruktor-Delegation und wird erst mit C++0x unterstützt.
TyRoXx schrieb:
Die zweite Sache:
Darf man das machen? Oder ist das bloß schlechter Stil? Oder etwa ganz normal?Nein. Ja. Nein. Diese Byte-Schiebereien darfst Du nur bei PODs (Plain Old Data structure) machen. int ist ein POD, ein struct ohne benutzerdefinierte konstruktoren, destruktoren, zuweisungsoperatoren und keine Referenz-Elemente ist auch ein POD. std::string ist kein POD. Da function bei Dir ein Template ist und für T alles mögliche zugelassen wird (zB auch std::string) ist das eine ganz schlechte Idee. PODs haben auch keine Destruktoren -- zumindest nicht welche, die man aufrufen müsste.
Prinzipiell muss man die Finger von den Bits und Bytes von nicht-PODs lassen. Man kann sie zwar irgendwo in einen Puffer konstruieren, muss sie dann aber auch schön wieder Zerstören. Bitfriemeleien nicht erlaubt.
Gruß,
SP
-
und weil du es "so schnell wie möglich" haben möchtest, dachtest du dir, du machst es erst mal so, dass es später irgendwann kracht - aber das zumindest schnell? uninitialized_fill ist def. nicht spürbar langsamer.
bei PODs wird es vermutlich mind. genau so schnell wie memcpy sein und bei nicht pods wird es so schnell sein, dass du es nicht schneller hinbekommst...bb