Folge dem Video um zu sehen, wie unsere Website als Web-App auf dem Startbildschirm installiert werden kann.
Anmerkung: Diese Funktion ist in einigen Browsern möglicherweise nicht verfügbar.
Soweit korrekt.Die Funktion push_back erstellt eine Kopie von deinem übergebenen Objekt.
Es gibt in C++ keinen "Copy Operator". Meinst du den Copy-Konstruktor?Du hast wahrscheinlich keinen Copy Operator definiert.
Wieso sollte der Compiler meckern? Ist kein Copy-Konstruktor deklariert, erzeugt der Compiler (in der Regel) automatisch einen Copy-Konstruktor.Normalerweise sollte dein Compiler bei dem Funktionsaufruf sofort meckern, aber anscheinend ruft deiner einfach den Standardkonstruktor, vermutlich Aufgrund der von Cromon genannten Tatsache der doppelten Konstruktordefinition, auf und du erhältst leere Objekte.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Liwanze {
public:
enum Region { ndef=0, amer, apac, emea };
Liwanze(const string& name, Region loc) : name(name), loc(loc) {
}
const string& get_name() const {
return name;
}
Region get_loc() const {
return loc;
}
private:
string name;
Region loc;
};
void populate(vector<Liwanze> &li) {
li.push_back(Liwanze("Sui", Liwanze::amer));
li.push_back(Liwanze("Mark", Liwanze::amer));
li.push_back(Liwanze("Robert", Liwanze::amer));
li.push_back(Liwanze("Ralph", Liwanze::apac));
li.push_back(Liwanze("Sven", Liwanze::amer));
}
int main() {
vector<Liwanze> lvz;
populate(lvz);
for (int i = 0; i < lvz.size(); ++i) {
cout << "Name: " << lvz.at(i).get_name()
<< " Region: " << lvz.at(i).get_loc() << endl;
}
return 0;
}
Das kann man so allgemein nicht sagen. Sobald eine Klasse Zeiger oder Referenzen enthält, erzeugt der Default-Copy-Konstruktor nur eine flache Kopie.By default ist in C++ eine Kopie eines Objekts eine deep copy (im Gegensatz zu vielen anderen (Script-)Sprachen). Das heisst auch alle Member werden kopiert.
Auch diese Aussage ist nicht allgemein gültig. Der Default-Copy-Konstruktor kann nicht immer automatisch generiert werden. Das ist zum Beispiel der Fall, wenn einer der Member nicht kopierbar ist.Mit 'by default' meine ich, wenn kein Copy-Konstruktor definiert ist. Es gibt keinen Fehler, wenn du diesen nicht implementierst, die Standardvariante (wenn keine eigene definiert wurde) ist wohldefiniert.
Das scheint mir eine nicht ganz zu Ende gedachte Übertragung der "Rule of Three" von C++03 (Destruktor, Copy-Konstruktor und Copy-Assignment-Operator immer gemeinsam definieren) auf C++11 zu sein. Der Move-Konstruktor ist für die Korrektheit nicht nötig (kann aber bei der Effizienz helfen). Andererseits gibt es auch Fälle, in denen man einen Move-Konstruktor, aber keinen Copy-Konstruktor haben möchte/kann (z.B. std::unique_ptr). Siehe weiterführend dazu http://stackoverflow.com/a/4782927/764214.Grundsätzlich muss ein copy-konstruktor nur im Rahmen der big-4 implementiert werden, also:
Wenn du einen der folgenden implementierst, implementiere alle:
1. Destruktor
2. Assignment-Operator
3. Copy-Constructor
4. Move-Constructor
Das kann man so allgemein nicht sagen. Sobald eine Klasse Zeiger oder Referenzen enthält, erzeugt der Default-Copy-Konstruktor nur eine flache Kopie.
Das kann man so allgemein nicht sagen. Sobald eine Klasse Zeiger oder Referenzen enthält, erzeugt der Default-Copy-Konstruktor nur eine flache Kopie.
Das scheint mir eine nicht ganz zu Ende gedachte Übertragung der "Rule of Three" von C++03 (Destruktor, Copy-Konstruktor und Copy-Assignment-Operator immer gemeinsam definieren) auf C++11 zu sein. Der Move-Konstruktor ist für die Korrektheit nicht nötig (kann aber bei der Effizienz helfen). Andererseits gibt es auch Fälle, in denen man einen Move-Konstruktor, aber keinen Copy-Konstruktor haben möchte/kann (z.B. std::unique_ptr). Siehe weiterführend dazu http://stackoverflow.com/a/4782927/764214.
class Foo
{
public:
virtual ~Foo();
Foo(const Foo&) = delete;
Foo(Foo&&);
Foo& operator = (const Foo&);
};
Liwanze(const Liwanze& orig);
Liwanze::Liwanze(const Liwanze& orig) {
}
Das klingt richtig, ist aber evtl. der Denkansatz, der in die falsche Richtung führt.
Der Zeiger ist nur ein Zeiger, und der wird sauber kopiert. Das, worauf er zeigt, natürlich nicht (ist ja auch nicht Bestandteil eines Pointers)
Wenn also das reine Kopieren des Zeigers eine tiefe Kopie ist, was wäre dann eine flache Kopie? Kopie und Reproduktion sind für mich Synonym, daher verstehe ich nicht was du damit sagen willst.Wie Endurion sagte ist das für mich so ein Grenzfall für die Klassifizierung. Wenn ich ein Objekt mit einem Zeiger kopiere ist für mich die Kopie der Adresse bereits eine deep copy, würde das Objekt worauf es zeigt kopiert hätte ja der Zeiger nacher auch einen anderen Wert, das entspricht für mich weniger einer Kopie sondern eher einer Art Reproduktion.
Wie kommst du denn darauf? Natürlich können solche Objekte kopiert werden.Referenzen werden gar nicht kopiert. Ein Objekt mit einer Referenz als Member ist nicht kopierbar.
Klar sollte man sich überlegen, ob Move-Semantik für eine Klasse sinnvoll ist oder nicht. Aber sofern meine Klasse kopierbar ist, sollte die Existenz eines Move-Konstruktors keinen Einfluss darauf haben, ob sie korrekt funktioniert. Ich sehe es daher nicht so, dass man in diesem Fall unbedingt den Move-Konstruktor implementieren muss. Beim Beispiel mit unique_ptr wollte ich darauf hinaus, dass man in diesem Fall keinen Copy-Konstruktor implementieren kann. Wenn du = delete als Implementierung siehst (was ich auch nachvollziehen kann), ist das natürlich ein schlechtes Beispiel Abgesehen davon müsste man sich die Arbeit nicht machen, den Copy-Konstruktor und den Copy-Assignment-Operator explizit als gelöscht zu definieren, da das schon implizit geschieht, sofern ein Move-Konstruktor vom Benutzer definiert wurde.Das ist eine (bis auf den move-assignment-operator) zu Ende gedachte Übertragung der Rule of Three von C++03 auf C++11. Für mich gehört es zur Korrektheit dazu sich genau diese Gedanken zu machen.