Forum: PC-Programmierung [C++] Von Objekt in Vektor auf Variable außerhalb zugreifen


von Andre G. (andgst01)


Lesenswert?

Schönen Abend,

ich habe aktuell ein kleines C++ Problem und stecke mental irgendwie 
fest.

Gibt es in C++ eine Möglichkeit um von einem Objekt das sich in einem 
Vektor befindet auf eine Variable des Objekts zuzugreifen in dem sich 
der Vektor befindet?

Ohne den Wert als Parameter einer Funktion zu übergeben.

Ich möchte die einzelnen Klassen möglichst funktionell von einander 
trennen, deshalb möchte ich das nicht mit Funktionsparametern 
realisieren.
Die Objekte im Vektor sollen sich bei Bedarf die Werte der Variablen 
selbst holen.


Kleines Beispielprogramm wie ich mir das vorstelle:
1
#include <iostream>
2
#include <vector>
3
4
using namespace std;
5
6
class Thing{
7
public:
8
  string Name;
9
  float Temperature;
10
  
11
  void GetRoomTemperature(void)
12
    {
13
      //INSERT CODE HERE
14
    }
15
};
16
17
class Room{
18
public:
19
  float RoomTemperature;
20
  vector <Thing> ThingsInRoom;
21
};
22
23
int main()
24
{
25
  Room MyRoom;                                // There will be a vector of rooms, this is just to show the basic problem
26
  MyRoom.RoomTemperature = 4.0;
27
  MyRoom.ThingsInRoom.push_back( {} );            //create a new "Thing" object and store it in the vector
28
  MyRoom.ThingsInRoom[0].Name = "Thermometer";    //give the new thing a name
29
  
30
  MyRoom.ThingsInRoom[0].GetRoomTemperature();
31
  
32
}

Vererbung geht nicht weil dann müsste ich ja Room vor Thing deklarieren 
und dann könnte Room keinen Vektor vom Typ Thing enthalten.

Globale Variablen gehen auch nicht denn es könnte ja einen Vektor von 
Room Objekten geben.

Also wie könnte man dieses Problem lösen?

von Jim M. (turboj)


Lesenswert?

C++ kennt Vorwärts Deklarationen (engl. forward declaration).

Das wäre eine mögliche Lösung für das Problem hier.

von Andre G. (andgst01)


Lesenswert?

Ok.
Dann kann ich die Variablen vererben aber das sind dann nur "Duplikate" 
der Variable der übergeordneten Klasse, kein direkter Zugriff darauf.
1
class Thing;
2
3
class Room{
4
public:
5
  float RoomTemperature;
6
  vector <Thing> ThingsInRoom;
7
};
8
9
class Thing : public Room{
10
public:
11
  string Name;
12
  float Temperature;
13
  
14
  void GetRoomTemperature(void)
15
    {
16
      cout << "Room Temperature = " << RoomTemperature << " °C" << endl;
17
    }
18
};

Klar könnt man die bei der Erzeugung jedes Objekts abfragen aber wenn 
man sehr viele Objekte hat kostet das sinnlos Rechenzeit.
Und bei jeder Änderung müsste man alle Variablen in den Objekten 
aktualisieren.

Besser wäre es wenn jedes "Thing" Objekt eine Methode hätte die den 
aktuellen Wert aus der "übergeordneten Klasse" holen kann (die in der 
sich der Vektor mit all den "Thing" Objekten befindet).
Diese Methode kann dann bei Bedarf aufgerufen werden anstatt immer alles 
aktualisieren zu müssen und Performance und Speicher zu verschwenden.


Langsam glaube ich es wäre besser eine Art "Globales Bus System" zu 
implementieren.
Jedes "Thing" Objekt hat eine eindeutige Nummer (Adresse) und kann durch 
globale Variablen Daten "anfordern" die dann in globalen Variablen 
abgelegt werden wo sie "abgeholt" werden können.

von Harald (hasanus)


Lesenswert?

Du lässt Thing wissen in welchem container es steckt, indem es eine 
Referenz zu ihm speichert:

class Thing{
 . . .
  private:
    Room & Location;
  public:
    Thing(Room & location): Location(location) {}
 . . .
}
Die muss beim push_back() in Room gesetzt sein:
  MyRoom.ThingsInRoom.push_back( { MyRoom } );

dann kannst du in Zeile 13 Location.RoomTemperature ansprechen.

damit der Compiler in class Thing die Klasse Room kennt musst Du die 
erwähnte forward declaration geben.

von Andre G. (andgst01)


Lesenswert?

Wow, danke!

Das funktioniert einwandfrei!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.