C++ Referenz-Objekte als Typ für vector?

C++11-LIKE

Cadet 1st Year
Registriert
Juli 2016
Beiträge
10
Hallo,

ich habe eine Klasse erstellt, welche unter anderem als Eigenschaft einen vector mit dem Typ <Object> enthält.
Nun möchte ich, wenn ich einen Raum/Room und ein paar Objekte/Objects erstellt habe, ausgewählte Objekte mit der Methode addObjects() diesem Vektor der Klasse übergeben. Wird jetzt ein Object an den Eigenschaften geändert, ändern sich natürlich nicht die Eigenschaften der gespeicherten Objekte im Vektor objects der Klasse Room. Gern hätte ich das aber so.:pcangry: Ich hatte darüber nachgedacht im Vektor Objekt-Referenzen zu speichern, aber das habe ich nicht hinbekommen. Dann dachte ich mir, dass die Methode set_name() gleichzeitig auch den Namen/name des entsprechenden Objektes im Vektor ändern soll, aber das ist doch keine "schöne" Lösung des Problems – vor allem deshalb nicht, weil ich später noch weitere Abfragen(z.B. ist der Objektname bereits in Verwendung?, …) und Funktionen(Objekt löschen, ...) hinzufügen möchte u.s.w. Der Code weiter unten ist ein Testprogramm für das "richtige" Projekt, wo die Klassen bereits voll(oder besser: fast eben) implementiert sind. Vielleicht kann mir jemand hier helfen das Problem auf eine "gute Art und Weise" zu lösen.

Code:
#include <iostream>
#include <vector>
#include <string>

class Room {
	class Object;
	std::vector<Object> objects;
	int nr;
public:
	class Object {
		std::string name;
	public:
		Object(std::string name) : name(name) {}
		~Object() {}
		std::string get_name() const { return name; }
		void set_name(const std::string& new_name) {
			name = new_name;
		}
	};
	Room(int nr) : nr(nr) {}
	~Room() {}
	int get_nr() const { return nr; }
	void set_nr(int new_nr) { nr = new_nr; }
	void addObjects(std::vector<Object> objects) {
		for (auto object : objects) {
			this->objects.push_back(object);
		}
	}
	void showAllObjectValues() {
		for (auto object : objects) {
			std::cout << object.get_name() << std::endl;
		}
		system("PAUSE");
		std::cout << "\n\n";
	}
};

int main() {

	Room r1(1);
	Room::Object obj1("box");
	Room::Object obj2("harpsichord");
	Room::Object obj3("sheet");
	r1.addObjects({ obj1, obj2, obj3 });
	r1.showAllObjectValues(); // box - harpsichord - sheet
	obj3.set_name("paper");
	r1.showAllObjectValues(); // natürlich immernoch: box - harpsichord - sheet

	return 0;
}


Vielen Dank im Voraus!

PS: Sorry, aber beim Titel hatte ich wirklich keine bessere Idee ... :confused_alt: :freak:
PPS: Der Code oben geht ohne Probleme zu kompilieren.
 
Hallo,

vector-en aus referenzen sind per definition illegal.
Also bleiben dir als option pointer (am besten std::unique_ptr, oder std::shared_ptr)
Oder auch std::reference_wrapper, was quasi ein pointer ist - und abstürzen wird, sobald die reference die gewrapped wird ihr scope verlässt.

Alternativ kannst du der Room klasse auch etwas vector funktionalität geben.
Wie z.b. "Gib mir das objekt mit namen/id X". Das könnte aussehen (an der Verwendungsstelle)
Code:
r1.getObjectByName("harpsichord").set_name("Paper");

Das ist dann ein wenig Geschmackssache.
 
r1.getObjectByName("harpsichord").set_name("Paper");

Super Idee: einfach die Objects als „Zwischen-Objekt“ nutzen, dem jeweiligen room hinzufügen und nur die Eigenschaften der im vector gespeicherten Objekte über Methoden ändern und dann nur mit diesen Objekt(-Eigenschaften) arbeiten!
Dein letzter Einfall hat mir wirklich weiter geholfen!

Danke!
 
Wenn du deine objekte schon eindeutig über einen string identifizierst solltest du dir unbedingt auch std::map statt std::vector angucken. Das ist nämlich genau das.. ein paar aus key (zb dein string) und dazu ein value (dein objekt)
Allerdings macht es dann keinen sinn mehr wenn das objekt selbst noch weiß wie es heißt und auch nciht, dass man den namen am objekt selbst ändern kann
 
Ich empfehle die Klasse Room und die Klasse Objekt voneinander in verschiedenen Header/Source Files zu trennen. Jedes erzeugt Objekt könnte zb eine static ID bekommen (sonst wir eine Nr mehrfach vergeben!) und darüber identifiziert werden. Darüber hinaus würde ich jedem Objekt per Konstruktor einen Namen zuweisen und die setName Funktion aus der Klasse löschen (die setNr Funktion auch). Und das Einbringen von Hilfsfunktionen, wie zb void showAllObjectValues() {} ein schlechter Stil. Hilfsfunktionen gehören im Idealfall in einen eigenen Namensbereich oder mindestens raus aus dem Interface des Typs. (die Hinweise mit den Pointern beachten!, generell zum sinnvollen Erstellen und Zerstören von Objekten, schau Dir das Fabrik-Muster an, allerdings ist das bereits weitergehend und nicht für Anfänger).
 
Zuletzt bearbeitet:
Zurück
Oben