Reputation:
I'm using pointers of class objects.Then i write in reservation file data.And if i read from .txt file i cannot read poiners.What's the good way to initialize pointers Should i use additional variables(userLogin,roomId) and then match additional variables with variables of objects and get address from them?
class Guest
{
public:
string login;
string password;
string name;
};
class Room
{
public:
int id;
string type;
};
class Reservation
{
public:
string checkOut;
string checkIn;
Room* room;
Guest* user;
string userLOgin;
int roomId;
};
class Manage
{
void MakeResrvation(Guest* user,Room* room,bool appendToFile)
{
string checkIn,checkOut;
ofstream writer(ReservationPath, appendToFile ? ios::app : ios::out);
if (writer.is_open()) {
writer<<room->id<<Delimiter<<user->login<<Delimiter<<checkIn<<Delimiter<<checkOut<<Delimiter;
writer<<endl;
}
}
vector<Reservation*> LoadFromFile() {
ifstream reader(ReservationPath);
vector<Reservation*> reservations;
if (reader.is_open()) {
string line;
while (getline(reader, line))
{
vector<string> items = Split(line, Delimiter);
Reservation* reservation = new Reservation;
reservation->roomId=stoi(items.at(0));
reservation->userLOgin=items.at(1);
reservation->checkIn=items.at(2);
reservation->checkOut=items.at(3);
reservations.push_back(reservation);
}
reader.close();
}
return reservations;
};
I expect to get pointer in the most optimized way.
Upvotes: 1
Views: 67
Reputation: 73446
It makes no sense to read a pointer from a file. A pointer is an address within the memory space. When you create your reservation, the pointer points to an address where a valid object (e.g. a Room
or a Guest
) is supposed to be stored:
void test()
{
Room r{12,"big room"};
Guest g{"XYZ","...","Mr XY, Z"};
manager.MakeReservation(&g, &r, true);
} // r and g are destroyed here
When you later read the pointer, you are not sure that a valid object is still at the place where it was before. In the example above, the pointers pointed to local objects, and these have been destroyed in the meantime.
Worse, if you would read the file from another process (e.g., when running your program again the next day) the address space might be completely different, and the object you where hoping pointing to might never have existed there.
In a Reservation
you have the key information to uniquely identify the objects you are looking for: roomId
should uniquely identify a Room
, and userLOgin
should uniquely identify a Guest
(at least I'll assume so hereafter), and regardless of the place where they are stored.
So what you need to do is to store somewhere repositories of rooms and guests: when you read your reservation, you need to search in the repository the corresponding objects, and set the pointers accordingly. OF course, you need to adapt your code: either pass the repositories as argument to the function that needs them, or store them as members of Manage
.
Another alternative, could be when you save the object, also save the data of the pointed objects. When you then read the data, you'd have to create not only the reservation, but also the "embedded" objects, and initialise the pointers accordingly. This is a little bit more complex, but you can google for serialization to know more about this process.
Attention when you write data, in case the strings you are writing contain the delimiter: this could lead to nasty bugs when reading the file.
I'd suggest also to use in reservation either a roomId
and always find the room in the repository when it's needed, or a pointer to Room
, knowing that the id can be found there. Having redundant information in Reservation
could lead weird things to happen such as pointing to an object with a different id than expected.
Now if you're managing your repositories in form of vector<Reservation*>
, vector<Room*>
, and vector<Guest*>
, you may be interested in using vector<shared_ptr<Reservation>>
, vector<shared_ptr<Room>>
, and vector<shared_ptr<Guest>>
, since shared_ptr
facilitates memory management.
Finally, for your repositories, you may consider using std::map
instead of std::vector
, where the key to the map would be the unique identifier.
Upvotes: 1