我的一个 friend 和其他人写了下面的代码,根据我的 C++ 知识应该是非常危险的:
Recovery& Recovery::LoadRecoverFile() {
fstream File("files/recover.dat", ios::in | ios::binary);
if (File.is_open()) {
while (!File.eof()) {
File.read(reinterpret_cast<char*>(this), sizeof(Recovery)); // <----- ?
}
}
File.close();
return *this; // <----- ?
}
你能告诉我你的意见为什么这是不好的吗?应该如何正确地做到这一点?
他们基本上将 Recovery 类的对象写入文件,并在需要时使用上述方法将其读入。
编辑: 只是为了提供有关代码的一些其他信息。这是 Recovery 类包含的内容。
class Recovery {
public:
Recovery();
virtual ~Recovery();
void createRecoverFile();
void saveRecoverFile( int level, int win, int credit, gameStates state, int clicks );
Recovery& LoadRecoverFile();
const vector<Card>& getRecoverCards() const;
void setRecoverCards(const vector<Card>& recoverCards);
int getRecoverClicks() const;
void setRecoverClicks(int recoverClicks);
int getRecoverCredit() const;
void setRecoverCredit(int recoverCredit);
int getRecoverLevel() const;
void setRecoverLevel(int recoverLevel);
gameStates getRecoverState() const;
void setRecoverState(gameStates recoverState);
int getRecoverTime() const;
void setRecoverTime(int recoverTime);
int getRecoverWin() const;
void setRecoverWin(int recoverWin);
private:
int m_RecoverLevel;
int m_RecoverCredit;
gameStates m_RecoverState;
};
这会将对象保存到文件中:
void Recovery::saveRecoverFile(int level, int win, int credit, gameStates state,
int clicks) {
m_RecoverLevel = level;
m_RecoverCredit = credit;
m_RecoverState = state;
ofstream newFile("files/recover.dat", ios::binary | ios::out);
if (newFile.is_open()) {
newFile.write(reinterpret_cast<char*>(this), sizeof(Recovery));
}
newFile.close();
}
它的用法是这样的:
m_Recovery.LoadRecoverFile();
credit.IntToTextMessage(m_Recovery.getRecoverCredit());
level.IntToTextMessage(m_Recovery.getRecoverLevel());
m_cardLogic.setTempLevel(m_Recovery.getRecoverLevel());
Timer::g_Timer->StartTimer(m_Recovery.getRecoverLevel() + 3);
最佳答案
可能是undefined behavior (除非 Recovery
是仅由标量场组成的 POD)。
如果 Recovery
可能行不通类有一个 vtable ,除非正在读取的进程可能与写入它的进程相同。 Vtable 包含函数指针(通常是一些机器代码的地址)。并且这些函数指针会因一个进程而异(即使它们运行相同的二进制文件),例如因为ASLR .
如果 Recovery
也行不通包含其他对象(例如 std::vector<std::shared_ptr<Recovery>>
....,或您的 gameStates
),因为这些子对象将无法正确构造。
有时它可以工作。但是您显然正在寻找的是 serialization (然后我建议使用像 JSON 这样的文本格式,但另请参阅 libs11n )或 application checkpointing .您应该从一开始就以这些目标设计您的应用程序。
关于在内存中修改自身的 C++ 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26550235/