如何从.txt文件中获取初始化的指针

How to get pointers initialized back from the .txt file

本文关键字:获取 初始化 指针 文件 txt      更新时间:2023-10-16

我正在使用类对象的指针。然后我写下预订文件数据。如果我从文件中读取.txt我就无法读取指针。初始化指针的好方法是什么 我是否应该使用其他变量(userLogin,roomId),然后将其他变量与对象的变量匹配并从中获取地址?

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;
};

我希望以最优化的方式获取指针。

为什么读取和写入指向文件的指针没有意义?

从文件中读取指针是没有意义的。指针是内存空间内的地址。 当您创建预订时,指针指向应该存储有效对象(例如RoomGuest)的地址:

void test() 
{
Room r{12,"big room"}; 
Guest g{"XYZ","...","Mr XY, Z"}; 
manager.MakeReservation(&g, &r, true);   
}    // r and g are destroyed here 

当您稍后阅读指针时,您不确定有效对象是否仍在它之前的位置。 在上面的示例中,指针指向本地对象,而这些对象在此期间已被销毁。

更糟糕的是,如果你从另一个进程读取文件(例如,第二天再次运行程序时),地址空间可能完全不同,你希望指向的对象可能永远不会存在。

如何解决您的问题?

Reservation中,您拥有唯一标识要查找的对象的关键信息:roomId应该唯一标识RoomuserLOgin应该唯一标识Guest(至少我在下文中会这样假设),并且无论它们存储在何处。

因此,您需要做的是在某个地方存储房间和客人的存储库:当您阅读预订时,您需要在存储库中搜索相应的对象,并相应地设置指针。 当然,您需要调整代码:要么将存储库作为参数传递给需要它们的函数,要么将它们存储为Manage的成员。

另一种选择可能是在保存对象时,也保存指向对象的数据。 然后读取数据时,不仅要创建预留,还要创建"嵌入"对象,并相应地初始化指针。 这有点复杂,但你可以谷歌进行序列化以了解有关此过程的更多信息。

其他改进

写入数据时要注意,以防您正在写入的字符串包含分隔符:这可能会导致读取文件时出现令人讨厌的错误。

我还建议在预订中使用roomId并在需要时始终在存储库中找到房间,或者指向Room的指针,知道 id 可以在那里找到。Reservation中存在冗余信息可能会导致奇怪的事情发生,例如指向 id 与预期不同的对象。

现在,如果你以vector<Reservation*>vector<Room*>vector<Guest*>的形式管理你的仓库,你可能对使用vector<shared_ptr<Reservation>>vector<shared_ptr<Room>>vector<shared_ptr<Guest>>感兴趣,因为shared_ptr便于内存管理。

最后,对于您的存储库,您可以考虑使用std::map而不是std::vector,其中映射的键是唯一标识符。