以C++为例子,通过操作内存模拟实现对象的持久化存储(一)

简介: 原创作者:岳东卫转载请写明 半夜突然兴起,于是乎有敲起了代码(哎!明早上又要旷课了 。。。): 我们用到过很多的对象序列化的,我在保存数据 传输数据的时候经常用到..用的多了 就想考虑下 像MFC  以及 java  和 boost库中他们到底是如何来实现序列化的  。

原创作者:岳东卫转载请写明

半夜突然兴起,于是乎有敲起了代码(哎!明早上又要旷课了 。。。):

我们用到过很多的对象序列化的,我在保存数据 传输数据的时候经常用到..用的多了 就想考虑下 像MFC  以及 java  和 boost库中他们到底是如何来实现序列化的  。

最近我在thiking in java的时候,遇到了Scanner类的具体使用.这个类可以从一个实现了Readable接口的类的对象中读取 数据,刚好我最近给我同学做的一个小的信息管理系统用到了对象的序列化 ,于是我就想自己覆盖这个类来实现可以从一个文件存储N个对象,以及从一个文件加载N个对象 ,  于是兴奋的动手开始做了。折腾了半天只能实现一个对象的读取,郁闷,看了Scanner这个类的源代码发现 Sun就是用来处理文本数据的 ,复用这个类来读取多个对象似乎不大可能 。。。没有复用的必要。。。于是我想自己写一个可以实现对象的存储到本地机器以及从文件加载对象而不用任何的库来辅助 、  下面开始 :

    我的思路是内存,因为我们知道我们所有的数据都是存储在内存中的二进制数据 。 那么可以知道 我们的程序中的类的对象在运行过程中也相应的在他进城的存储

空间中对应一段二进制数据,那么我们是否可以将这个数据保存到本地然后从本地加载,我就兴奋的去尝试了,下 果然可以....原来对象序列化的原理是如此简单:

说道这里下面代码只完成了 简单的包含基本数据类型和方法的类进行序列化 ...经验证可以实现简单序列化 。。。

#include <iostream>
#include <fstream>
#include <string>
using  namespace std ;
template <class T> 
class MyObject
{ 
public :
	 MyObject(T x)
	 {  
		cout<<"对象构造中!"<<endl ;
		this->x=x ;
			 }
	 ~MyObject()
	 {
	 }
	 static  void StoreObject(MyObject *obj)
	 {
    	long length=sizeof(*obj) ;
	    ofstream *o=new ofstream("c:\\obj.xxx") ;
    	o->write((char*)obj,length) ;
		o->close() ;
		delete o ;
	 }
	 static MyObject LoadObject(string file)
	 {
         char buf[1000] ;
    	 ifstream i(file.c_str()) ;
	     i>>buf ;
	      MyObject *p=(MyObject*)buf ;
		 i.close() ;
		 return (*p);
	 }
 	MyObject ShowX()  //一段最简单的代码
	{
	 cout<<"x="<<x<<endl ;
	 return (*this) ;
	}

private :
	int x ;
}  ;

int main()
{   
    MyObject<int> obj(443);
	MyObject<int>::StoreObject(&obj) ;
	MyObject<int>::LoadObject("c:\\obj.xxx").ShowX();
	return 0 ;
}


紧接着问题由来了,的确上面的代码可以实现简单对象的序列化但是,,当类的成员是另一个类的实例的时候,那么又应该怎么弄呢? 再运行下面代码发现 ,程序在序列化到文件的时候崩溃了...什么原因呢 。。这根我们在java中和MFC对于成员对象序列化一样,在java中如果成员对象没有实现Serializable接口那么那么就会抛出一个异常 ,

在MFC中如果不成员对象所在的类如果不从CObject派生以及 增加一些宏定义那么也会程序崩溃。。看下面代码在上面代码修改后就出现了问题。程序就会崩溃。。。 

对于类内部的成员对象如何进行进一步的一层一层的序列化呢?这个问题麻烦了..... 下次在继续 睡觉 。。。

#include <iostream>
#include <fstream>
#include <string>
using  namespace std ;
class Data
{
	 public:
	   void OutPut()
	   {
		   cout<<"输出成员对象!"<<endl ;
	   }
} ;
template <class T> 
class MyObject
{ 
public :
	 MyObject(T x)
	 {  
		 cout<<"对象构造中!"<<endl ;
		this->x=x ;
		
		dt=new Data() ;
	 }
	 ~MyObject()
	 {
		 delete dt ;
	 }
	 static  void StoreObject(MyObject *obj)
	 {
    	long length=sizeof(*obj) ;
	    ofstream *o=new ofstream("c:\\obj.xxx") ;
    	o->write((char*)obj,length) ;
		o->close() ;
		delete o ;
	 }
	 static MyObject LoadObject(string file)
	 {
         char buf[1000] ;
    	 ifstream i(file.c_str()) ;
	     i>>buf ;
	      MyObject *p=(MyObject*)buf ;
		 i.close() ;
		 return (*p);
	 }
 	MyObject ShowX()  //一段最简单的代码
	{
	 cout<<"x="<<x<<endl ;
	 return (*this) ;
	}

private :
	int x ;
	Data *dt;
}  ;

int main()
{   
    MyObject<int> obj(443);
	MyObject<int>::StoreObject(&obj) ;
	MyObject<int>::LoadObject("c:\\obj.xxx").ShowX();
	return 0 ;
}


 

目录
相关文章
|
6月前
|
安全 C语言 C++
比较C++的内存分配与管理方式new/delete与C语言中的malloc/realloc/calloc/free。
在实用性方面,C++的内存管理方式提供了面向对象的特性,它是处理构造和析构、需要类型安全和异常处理的首选方案。而C语言的内存管理函数适用于简单的内存分配,例如分配原始内存块或复杂性较低的数据结构,没有构造和析构的要求。当从C迁移到C++,或在C++中使用C代码时,了解两种内存管理方式的差异非常重要。
241 26
|
11月前
|
存储 程序员 编译器
玩转C++内存管理:从新手到高手的必备指南
C++中的内存管理是编写高效、可靠程序的关键所在。C++不仅继承了C语言的内存管理方式,还增加了面向对象的内存分配机制,使得内存管理既有灵活性,也更加复杂。学习内存管理不仅有助于提升程序效率,还有助于理解计算机的工作原理和资源分配策略。
|
11月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
7月前
|
C语言 C++
c与c++的内存管理
再比如还有这样的分组: 这种分组是最正确的给出内存四个分区名字:栈区、堆区、全局区(俗话也叫静态变量区)、代码区(也叫代码段)(代码段又分很多种,比如常量区)当然也会看到别的定义如:两者都正确,记那个都选,我选择的是第一个。再比如还有这样的分组: 这种分组是最正确的答案分别是 C C C A A A A A D A B。
144 1
|
11月前
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)
|
10月前
|
存储 Linux C语言
C++/C的内存管理
本文主要讲解C++/C中的程序区域划分与内存管理方式。首先介绍程序区域,包括栈(存储局部变量等,向下增长)、堆(动态内存分配,向上分配)、数据段(存储静态和全局变量)及代码段(存放可执行代码)。接着探讨C++内存管理,new/delete操作符相比C语言的malloc/free更强大,支持对象构造与析构。还深入解析了new/delete的实现原理、定位new表达式以及二者与malloc/free的区别。最后附上一句鸡汤激励大家行动缓解焦虑。
|
10月前
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
|
10月前
|
存储 编译器 C++
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。
|
10月前
|
存储 Java
课时4:对象内存分析
接下来对对象实例化操作展开初步分析。在整个课程学习中,对象使用环节往往是最棘手的问题所在。
|
10月前
|
编译器 C++
类和对象(下)C++
本内容主要讲解C++中的初始化列表、类型转换、静态成员、友元、内部类、匿名对象及对象拷贝时的编译器优化。初始化列表用于成员变量定义初始化,尤其对引用、const及无默认构造函数的类类型变量至关重要。类型转换中,`explicit`可禁用隐式转换。静态成员属类而非对象,受访问限定符约束。内部类是独立类,可增强封装性。匿名对象生命周期短,常用于临时场景。编译器会优化对象拷贝以提高效率。最后,鼓励大家通过重复练习提升技能!