Konstruktor
-
private bedeutet nur, daß niemand außerhalb deiner Klasse auf die Elemente zugreifen darf. Der Konstruktor gehört auch zur Klasse, deshalb ist ihm das egal (die eigenen Methoden einer Klasse dürfen auf alle Elemente dieser Klasse zugreifen, außer auf private Elemente der Basisklasse - aber in dem Fall sollte sich auch die Basisklasse um die Verwaltung kümmern).
-
Okey. Aber dann frage ich mich, wie denn der Vektor assignments initialisiert werden muss.
Ich dachte mit: _assignments.push_back(id, floors_, [usw]);
Aber das funktioniert so nicht.
-
sollte es eigentlich - du mußt nur wissen, was du das reinpackst (und daß du dort einen Vector von Vectoren hast). Zeig doch mal ein Beispiel inklusive der Klassendeklaration und deinem Versuch, den Vector zu füllen.
(achja, push_back() nimmt nur einen Parameter entgegen - wenn du mehrere Elemente haben willst, mußt du jedes einzelne angeben. In C++0x gibt es einige Änderungen/Erweiterungen für die Initialisierung, da könnte der Code etwas kürzer werden)
PS: Was soll diese Konstruktion eigentlich darstellen? Und woher kommen die person-Zeiger auf der innersten Ebene des Vector?
-
Also, ich habs nun wie folgt gemacht:
#include "building.hpp" // STL #include <iostream> #include <vector> building::building(int id_, int floors_, int rooms_per_floor_) : _id(id_), _floors(floors_), _rooms_per_floor(rooms_per_floor_) { this->_id = id_; this->_floors = floors_; this->_rooms_per_floor = rooms_per_floor_; } building::~building() { // Code } void building::assign_room(person* tenant_, int floor_, int room_) { //?? _assignments.push_back(tenant_); } person* building::free_room(int floor_, int room_) { // Code } void building::print_floor(int floor_number_) { std::cout << "Floor: " << floor_number_ << std::endl; for(int index = 0; index < _rooms_per_floor; ++index) { std::cout << "Room: " << index + 1; if(_assignments[floor_number_ - 1][index] != NULL) { std::cout << std::endl; _assignments[floor_number_ - 1][index]->print(); } else { std::cout << " not assigned!" << std::endl; } } } void building::print() { std::cout << "Building: " << _id << std::endl; std::cout << "Number of Floors: " << _floors << std::endl; std::cout << "Number of Rooms: " << _floors * _rooms_per_floor << std::endl; }Das header-file sieht so aus:
#ifndef BUILDING_H #define BUILDING_H // Task3 #include "person.hpp" // STL #include <string> #include <vector> class building { public: /** * @brief create a new building with specified number of * floors and number of rooms per floor */ building(int id_, int floors_, int rooms_per_floor_); /** * @brief the destructor is responsible for removing all * the persons from the building and freeing the * memory occupied by them. */ ~building(); /** * @brief assign a person to the own room */ void assign_room(person* tenant_, int floor_, int room_); /** * @brief remove the tenant associated to the room */ person* free_room(int floor_, int room_); /** * @brief print the information about the room, that is * - id of the building * - floor number * - room number + person occupying it */ void print_floor(int floor_number_); /** * @brief prints informations about the building */ void print(); /** * @brief swap the tenants living in two rooms in the * actual building */ bool swap_tenants(int source_room_, int destination_room_); private: /* id of the building */ int _id; /* number of floors in the building */ int _floors; /* number of rooms contained in each floor */ int _rooms_per_floor; /* data structure representing the rooms placed in each floor of the building. In each room there is a person assigned to it. It is also possible that no person is initially assigned to it. NB: indexes start with 0 but the numbers to be shown start with 1! */ std::vector< std::vector<person*> > _assignments; }; #endif // BUILDING_HAllerdings habe ich eine Frage zur assign_room-Funktion. Man soll dort ja einen Raum einer Person zuweisen. (1 Raum pro Person)
Ich weiss aber nicht, was ich hier aufrufen und was wem zuweisen sollte...
-
Du hast einen vector, in dem vector<person*> untergebracht werden. Und wenn ich mir den Kommentar dazu so ansehe und die Funktion-Signatur der assign_room() ansehe, solltest die Person genau in den angegebenen Raum packen:
building::building(int id_, int floors_, int rooms_per_floor_) : _id(id_), _floors(floors_), _rooms_per_floor(rooms_per_floor_), _assignments(floors_, vector<person*>(rooms_per_floor)) //das initialisiert den vector mit den übergebenen Größen { /* // das hier brauchst du nicht, die Werte wurden schon durch die Initialisierungsliste übernommen this->_id = id_; this->_floors = floors_; this->_rooms_per_floor = rooms_per_floor_; */ } void building::assign_room(person* tenant_, int floor_, int room_) { _assignments[floor_][room_] = tenant_; }
-
Allerdings habe ich eine Frage zur assign_room-Funktion. Man soll dort ja einen Raum einer Person zuweisen. (1 Raum pro Person)
Ich weiss aber nicht, was ich hier aufrufen und was wem zuweisen sollte...Über so etwas macht man sich normalerweise Gedanken bevor man eine Klasse programmiert... Du solltest dich fragen, wie der Zugriff passieren soll, soll der Raum die Person kennen oder die Person den Raum. Muss der Raum die Personen kennen die in ihm sind? usw.
Vielleicht solltest du dein komplettes Design ändern!? z.B. Eine "Klasse Gebäude", hat einen oder mehrere "Klasse Stock", diese haben keinen, einen oder mehrere "Klasse Raum"... und ein Raum hat einen Zeiger auf eine Person.
-
@CStoll
Ahhh..okey. Nur: Mein Compiler reklamiert bei vector<person*>(rooms_per_floor_)): "'vector': nichtdeklarierter Bezeichner".@HighLigerBiMBam
Naja..ich hätte auch einiges anders gemacht. Aber übungshalber muss (sollte) ich es so lassen und so implementieren, wie es halt im header vorgegeben wurde.
-
So viel Mitdenken könnte man doch schon erwarten

~versuch's mal mit "std::vector"~@BimBam: Man kann es mit der Abstraktion auch übertreiben. Wenn du nicht gerade eine Software für Architekten entwirfst, dürfte es ausreichen, die Raumaufteilung in der Gebäude-Klasse zu speichern.
-
Ahhh..sh...
Okey, evtl. ist die späte Stunde schuld
(aber wenigstens hab' ich den Fehler beim Argument bemerkt
)Eine Schlussfrage habe ich noch.
Es gibt ja die Destruktor-Funktion.
Dort muss ich doch den _assignments-vector löschen.
Wie aber schreibe ich das korrekt?
Mit "delete _assignments;" reklamiert mein Compiler...
-
Um den vector mußt du dich überhaupt nicht kümmern, das macht schon dessen Destruktor. Worüber du dir eventuell Gedanken machen solltest, sind die person-Objekte, die auf der untersten Ebene des Vektors gespeichert werden. Aber da ich nicht weiß, wer (und wie) die erzeugt und an die assign_room() übergibt, kann ich dazu nichts genaueres sagen.
-
Also erzeugt und zugewiesen werden sie in der main-Funktion einer anderen Klasse.
Hier ein Code-Snippet:main(void) { person* first = new person("Valentino", "Rossi", "via Bologna 84",1); building woko_first(1,2,4); woko_first.assign_room(first,2,4); /... }Allerdings gelingt es mir trotzdem nicht, die Person-Objekte zu deleten.
-
Einfachste Lösung: Wenn die main()-Funktion die Personen anlegt, sollte sie sie auch wieder löschen

Nächstbeste Lösung: Verwende einen vernünftigen Smart-Pointer anstelle der nackten Zeiger (z.B. shared_ptr)
Wenn du dich unbedingt selber darum kümmern willst, mußt du mit einer doppelten Schleife durch den Vector durchlaufen und jedes einzelne Element per delete löschen.
PS:
MaxC++ schrieb:
building woko_first(1,2,4); woko_first.assign_room(first,2,4); }Autsch - Die Indizes beginnen bei 0, d.h. der Raum 2/4 liegt außerhalb des vom Vector verwalteten Speicherbereiches.
-
Okey, angenommen, ich entscheide mich für die Schleifen-Methode.
Wie bekomm ich da den Vektor mit den jeweiligen Elementen?
Ich dachte, ich könne die Personen einfach per "person::person[1]" erreichen.Zu deiner Bemerkung:
Schau Dir mal das Header-File aus einem vorherigen Post an. Das ist doch so gedacht, oder seh' ich das falsch?
-
Du erreichst die Person (bzw. den person*-Zeiger im Vector) in Raum y aus Etage x per
_assignments[x-1][y-1]- zum Löschen mußt du alle Kombinationen von x und y durchlaufen.MaxC++ schrieb:
Zu deiner Bemerkung:
Schau Dir mal das Header-File aus einem vorherigen Post an. Das ist doch so gedacht, oder seh' ich das falsch?Stimmt auch wieder - da mußt du dann in allen Methoden die Koordinaten umrechnen.
-
Jeps, hab ich gemacht. (sehr mühsam..aber was solls)
Dafür klappt nun alles. YES
Vielen Dank für die Hilfe!
-
PS: Kann ich das so machen, oder funktioniert es nur "per Zufall"?
Weil irgendwie hab ich mir das komplizierter vorgestellt.for(int x=1; x<_floors; x++) { for(int y=1; y<_rooms_per_floor; y++) { delete _assignments[x-1][y-1]; } }
-
Genau so habe ich das gemeint - nur solltest du nochmal nachzählen, ob du mit der Schleife wirklich alle Einträge erwischst.
-
Eben..deshalb die PS-Frage

..aber ich denke, dass ich so alle Einträge erreichen sollte, weil die Schleifen ja verschachtelt sind, und nicht nacheinander einzeln aufgerufen werden.
Mit den Beispiel-Werten funktioniert's auf alle Fälle.
-
Leide nicht - Die Schleifen selber sind in Ordnung, die Abbruchbedingungen stimmen nicht ganz (du verfehlst das Dachgeschoß und den letzten Raum jeder Etage).
-
Also einfach wie folgt korrigieren?
for(int x=1; x<_floors+1; x++) { for(int y=1; y<_rooms_per_floor+1; y++) { delete _assignments[x-1][y-1]; } }