2016-06-11 4 views
0

Wenn ich eine Klasse haben:Verhalten, wenn Sie setzen ein Element eines Vektors der Klassen gleich einer Klasse

Class aClass 
{ 
    vector<aClass> connections; 
} 

mit allem anderen richtig erklärt, wenn ich tun waren:

aClass a = new aClass(); 
aClass b = new aClass(); 

b.connections.push_back(a); 

würde dies einen Verweis auf a erstellen oder würde es die Klasse duplizieren.

Ich möchte, dass es ein Zeiger auf die Klasse ist, aber ich war mir nicht sicher, ob ich zusätzliche Syntax benötigt, um dies zu gewährleisten. Ich erinnere mich zu lesen, dass, wenn eine Klasse aClass a = new aClass deklariert wird, es einen Zeiger auf das Objekt im Heap erstellt, aber ich war mir nicht sicher, was hier passieren würde.

Als Referenz ist dies für so etwas wie eine verknüpfte Liste.

Auch wenn jemand einen besseren Titel für diese Frage vorstellen kann, gehen Sie voran und bearbeiten Sie es.

Antwort

2
  1. connections sollte vector<aClass*> sein sollte aClass aaClass* a sein.

  2. Dann wird für b.connections.push_back(a); der Wert des Zeigers kopiert, nicht der Zeiger (d. H. Das Objekt, auf das gezeigt wird).

  3. Ich schlage vor, Sie verwenden smart pointers anstelle von rohen Zeigern, wenn Sie Zeiger wie std::vector<std::shared_ptr<aClass>> verwenden möchten.

+0

Danke, ich habe seit ein paar Jahren nicht viel C++ Programmierung gemacht, also konnte ich mich nicht genau erinnern, was hier passieren würde. – Cjen1

+0

Als eine Frage über Zeiger, wenn ein Programm geschlossen ist und es noch Zeiger gibt, die auf Objekte verweisen, werden diese Objekte gelöscht und Müll gesammelt? oder werden sie einen Speicherverlust verursachen – Cjen1

+0

@ Cjen1 Wenn Sie rohen Zeiger verwenden, '' 'neues' '' st '' löscht'' es, dann verursacht Speicherverlust. Deshalb habe ich intelligente Zeiger vorgeschlagen. – songyuanyao

0

Erstens, vector<aClass> ist kein Vektor von Klassen, es ist ein Vektor von Instanzen einer Klasse.

Zweitens ist aClass a = new aClass(); schwer zu kompilieren in C++. In den meisten Fällen wird eine standardmäßig konstruierte Instanz einer Klasse einfach als aClass a; erstellt, und new aClass() gibt normalerweise einen Zeiger an eine neue Instanz der Klasse zurück.

Drittens, auch wenn Sie eine Instanz zu dem Vektor push_back ist, wird es kopiert.

Für Standard-konstruierten Objekte, ein frisches Objekt am Ende des Vektors durch resize ing den Vektor von 1.

Seit 2011 bauen können, können Sie eine Instanz über Nicht-Standard-Konstruktor (mit nicht konstruieren (leerer Satz von Konstruktionsargumenten) direkt innerhalb des Vektors unter Verwendung von emplace_back.

0

Wenn der Code gemacht wird übersetzbar zu sein, was ich denke, was Sie bestimmt dann:

Die documentation sagt, dass ist, hat 2 Überlastungen

void push_back(const T& value); 
void push_back(T&& value); 

Also, solange sie nicht ausdrücklich std::move oder geben Sie cast oder push_back Rückgabewert von einer Funktion ein, dann wird die erste Überladung ausgelöst, was bedeutet, dass das Kopieren push_back aufgerufen wird. Sonst wird der zweite, bewegende genannt.

EDIT: Typ gegossen und std::move ist das Gleiche unter der Haube. Aber, es behält const Korrektheit, also, wenn Sie const T passierten, dann wird es std :: move es const T&& machen, das in der Überladungsauflösung sehr gefährlich ist.

Sie sollten nicht const T&& jemals übergehen, warum lesen here.

0
aClass a = new aClass(); 
aClass b = new aClass(); 

b.connections.push_back(a); 

Es nicht einmal kompilieren. Wie jemand erwähnt, sollten Sie aClass *a und aClass *b schreiben.

Dies wird den Wert in den Vektor kopieren, weil Ihr Vektor aClass Objekte (Werte, keine Adressen) enthält. Es kopiert keine Adresse. wenn Sie so etwas wie dies jedoch tun

vector<aClass*> connections; 
aClass *a = new aClass(); 
aClass *b = new aClass(); 
b.connections.push_back(a); 

Dann wird ein Vektor wird einen Zeiger auf aClass Objekte (Instanzen von aClass) halten. In diesem Fall zeigen die Verbindungen [0] auf a Objekt. Und wenn Sie das tun ::

cout << connections[0]<< endl; 
cout << a << endl; 

Dann sind diese Zeilen gleich. Sie werden das gleiche ausdrucken (gleiche Adresse).

Schließlich, wenn Sie löschen, dass a Objekt:

delete a; 

Dann wird es an dieser Stelle im Speicher zeigen, dass das Objekt in platziert wurde, aber es gibt keine a Objekt mehr. So können Sie nicht tun:

cout << a << endl; 

Sie können aber nach wie vor tun:

cout << connections[0] << endl; 

Und es wird die gleiche Adresse wie vor drucken.