user11444176
user11444176

Reputation:

How to get pointers initialized back from the .txt file

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

Answers (1)

Christophe
Christophe

Reputation: 73446

Why it doesn't make sense to read and write pointers to files ?

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.

How to solve your problem ?

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.

Other improvements

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

Related Questions