我有以下类,这些类我以二进制模式保存在文件中:
class lol
{
public:
~lol() {
std::cout << "destucted" << std::endl;
system("pause");
}
int age;
std::string name;
};
现在在我的主要位置,我有一个:
int main()
{
{
lol kar;
kar.age = 17;
kar.name = "Blabla";
ytxt("class").Write(std::string((char*)&kar, sizeof(kar))); //Saves the class in binary mode
}
lol * asd;
{
std::string stClass = ytxt("class").Read();//reads the file in binary
asd = (lol*)new char[stClass.length()];//asd is now allocated with new
memcpy_s(asd, stClass.length(), stClass.c_str(), stClass.length());//copy the content of the file into the class
}
std::cout << "Name: " << asd->name << std::endl;//output
std::cout << "Age: " << asd->age << std::endl;
asd->age = 79;
std::cout << "Age: " << asd->age << std::endl;
delete asd;//I cannot delete it as lol
//delete (char*)asd;//works but lol destructor is not called
system("pause");
}
asd
指针的内容被打印到控制台,指针被删除并称为击曲线。最后,抛出了例外。
当我不删除asd
指针时,一切正常工作,但是asd
指针的破坏者未调用。我知道指针被分配为new char
,我必须将其删除为new char
,但是还有另一种删除操作称为lol
的击球函数的方式吗?
ytxt("class").Write(std::string((char*)&kar, sizeof(kar)));
此行确实保存了一个字节的转储。但是,您不能加载字节的转储,并期望它再次成为课程的适当实例。这不是二元序列化的工作方式。这仅适用于POD类型(也可能不是通过该精确行)。如果要保存数据并稍后加载,则需要其他方法。
您程序中的所有其他问题都归结为具有正确数据的字节垃圾。
即使您修复了击曲率,此代码也没有工作的机会:存储包含指针的对象的字节,然后尝试将该对象还原到另一个内存是不正确的。
您的lol
类具有std::string
,该类存储指向字符串实际字节的指针。当您将kar
的字节复制到文件中时,您可以从运行程序中存储指针,并且不存储字符串本身的内容。
当您从文件中恢复lol
的实例时,其指针指向kar
的Destructor已将其解散的一块内存。这是未定义的行为。
您需要更改序列化对象的方法。您目前无法挽救的方法。
注意:当您将类分配为一个字节数组的内存中时,需要 new
操作员。请参阅此Q&amp; a,以获取有关新放置后如何进行清理的信息。
因为您的LOL类包含一个std :: String,它是一个复杂的对象并且具有内部内存管理,试图在它实际上不是真实对象时删除它来自文件的字节将导致内存损坏/崩溃。
只有一些C 结构才能写入并读取为原始字节,并以合理的方式工作。以这种方式工作的种类称为"普通旧数据",或简称POD。(在C 11中,它们将其分解为更细的粒状概念,但这是一个细节。)
struct或class(默认公共与私有的东西外,除了吊舱,没有虚拟,没有毁灭者,没有构造函数和内置类型,例如int
或Pointers and Pointers and Arrays to Clo Clone of CLESS,都不是纯旧数据。<<<<<<<<
阅读/写下这些碎片至少有一半明智的事情。
如果它包含指针,那么指向过去的程序无法生存的地址重新启动,因此请避免。
std::string
不符合条件,也没有任何包含它的东西。
要从文件中保存/加载,您应该查看序列化问题。有很多技术,但它们都不是免费的。
很容易地为某些输出存档类型put_here
定义免费的save( put_here, X const& _
功能。然后为您要支持的每种类型创建过载。对于load
做同样的事情。对于复合类型,只需保存/加载每个元素。
添加标签等用于版本控制也在非平凡的代码中也很有用。
对于诸如字符串之类的序列容器,您可以将其保存为save(here, str.size()); for (auto&&c:str)save(here, c);