如何将一个 内存 模拟成一个C++流,
把一个内存new出来后,在这段内存上面建立一个 C++ 的istream类.以后所有的操作都可以对这个istream类进行.
这样做有很多好处,比如,你的资源分析器可以接受一个istream指针,这个istream可能是一个fstream.也可能是你从zip文件中解出到内存后,从内存构造的一个istream.
具体做法是,从basic_streambuf里派生一个类,
这里只介绍一个简单的支持输出的streambuf.如果谁完善了它,或者实现了一个支持各种特性,输入输出,block buffer等功能的时候,麻烦也告诉我一下.不胜感激.
#ifndef __MEM_STREAM_BUFFER_H__<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
#define __MEM_STREAM_BUFFER_H__
/*
提供 C++ 标准库的扩展。支持从一段内存上建立一个istream类。
作者: 潘李亮 2004 - 10 - 25
Xheartblue 2004-10-25
本代码为免费代码,可以只有使用和修改。
但是你得保留本声明和作者名字。
*/
#include <streambuf>
namespace std
{
template <typename _CharT, typename _CharTrait = char_traits<_CharT> >
class mem_streambuf : public basic_streambuf<_CharT,_CharTrait>
{
public: //类型的定义
typedef _CharT streambuf_type;
typedef _CharT char_type;
typedef int int_type;
typedef typename std::streampos pos_type;
typedef typename std::streamsize off_type;
protected:
size_t m_bufLen;
char_type* m_buffer;
bool m_bIsAllocInner;
public:
//构造函数
mem_streambuf(char_type* buf,size_t len)
{
set_buf(buf,len);
}
mem_streambuf()
{
m_buffer = NULL;
m_bufLen = 0;
m_bIsAllocInner = false;
}
mem_streambuf(size_t len)
{
m_buffer = NULL;
m_bufLen = 0;
m_bIsAllocInner = false;
alloc_buf(len);
_init();
}
~mem_streambuf()
{
dealloc_buf();
}
bool alloc_buf(int len)
{
dealloc_buf();
m_buffer = new char_type[len];
m_bIsAllocInner = true;
m_bufLen = len;
return true;
}
bool set_buf(char_type* buf,size_t len)
{
m_buffer = buf;
m_bufLen = len;
m_bIsAllocInner = false;
_init();
return true;
}
bool dealloc_buf()
{
if(m_bIsAllocInner)
{
delete [] m_buffer;
}
m_buffer = NULL;
m_bufLen = 0;
m_bIsAllocInner = false;
return true;
}
char_type* get_buf()
{
return m_buffer;
}
protected:
void _init()
{
setg(m_buffer,m_buffer,m_buffer+ m_bufLen);
setp(m_buffer,m_buffer,m_buffer+ m_bufLen);
}
};//endl class mem_streambuf;
template <typename _CharT , typename _CharTrait = char_traits<_CharT> >
class basic_imemstream : public basic_istream<_CharT,_CharTrait>
{
public:
typedef mem_streambuf<_CharT,_CharTrait> stream_type;
typedef _CharT char_type;
protected:
stream_type m_buffer;
public:
basic_imemstream(stream_type* buf): basic_istream<_CharT,_CharTrait>(buf)
{
}
basic_imemstream(char_type* buf,size_t len)
:m_buffer(buf,len),basic_istream<_CharT,_CharTrait>(&m_buffer)
{
}
basic_imemstream():m_buffer(),basic_istream<_CharT,_CharTrait>(&m_buffer)
{
}
basic_imemstream(int len)
:m_buffer(len),basic_istream<_CharT,_CharTrait>(&m_buffer)
{
}
void set_buf(char_type* buf,int len)
{
m_buffer.set_buf(buf,len);
}
char_type* get_buf()
{
return m_buffer.get_buf();
}
basic_streambuf<_CharT,_CharTrait>* rdbuf()
{
return &m_buffer;
}
void rdbuf(basic_streambuf<_CharT,_CharTrait>* buf)
{
m_buffer = buf;
}
};
template <typename _CharT , typename _CharTrait = char_traits<_CharT> >
class basic_omemstream : public basic_ostream<_CharT,_CharTrait>
{
public:
typedef mem_streambuf<_CharT,_CharTrait> stream_type;
typedef _CharT char_type;
protected:
stream_type m_buffer;
public:
basic_omemstream(stream_type* buf): basic_ostream<_CharT,_CharTrait>(buf)
{
}
basic_omemstream(char_type* buf,size_t len)
:m_buffer(buf,len),basic_ostream<_CharT,_CharTrait>(&m_buffer)
{
}
basic_omemstream():m_buffer(),basic_ostream<_CharT,_CharTrait>(&m_buffer)
{
}
basic_omemstream(int len)
:m_buffer(len),basic_ostream<_CharT,_CharTrait>(&m_buffer)
{
}
void set_buf(char_type* buf,int len)
{
m_buffer.set_buf(buf,len);
}
char_type* get_buf()
{
return m_buffer.get_buf();
}
basic_streambuf<_CharT,_CharTrait>* rdbuf()
{
return &m_buffer;
}
void rdbuf(basic_streambuf<_CharT,_CharTrait>* buf)
{
m_buffer = buf;
}
};
template <typename _CharT , typename _CharTrait = char_traits<_CharT> >
class basic_memstream : public basic_ostream<_CharT,_CharTrait>,public basic_istream<_CharT,_CharTrait>
{
public:
typedef mem_streambuf<_CharT,_CharTrait> stream_type;
typedef _CharT char_type;
protected:
stream_type m_buffer;
public:
basic_memstream(stream_type* buf)
: basic_ostream<_CharT,_CharTrait>(buf),
basic_istream<_CharT,_CharTrait>(buf)
{
}
basic_memstream(char_type* buf,size_t len)
:m_buffer(buf,len),
basic_ostream<_CharT,_CharTrait>(&m_buffer),
basic_istream<_CharT,_CharTrait>(&m_buffer)
{
}
basic_memstream()
:m_buffer(),
basic_ostream<_CharT,_CharTrait>(&m_buffer),
basic_istream<_CharT,_CharTrait>(&m_buffer)
{
}
basic_memstream(int len)
:m_buffer(len),
basic_istream<_CharT,_CharTrait>(&m_buffer),
basic_ostream<_CharT,_CharTrait>(&m_buffer)
{
}
void set_buf(char_type* buf,int len)
{
m_buffer.set_buf(buf,len);
}
char_type* get_buf()
{
return m_buffer.get_buf();
}
basic_streambuf<_CharT,_CharTrait>* rdbuf()
{
return &m_buffer;
}
void rdbuf(basic_streambuf<_CharT,_CharTrait>* buf)
{
m_buffer = buf;
}
};
typedef basic_imemstream<char> imemstream;
typedef basic_imemstream<wchar_t> wimemstream;
typedef basic_omemstream<char> omemstream;
typedef basic_omemstream<wchar_t> womemstream;
typedef basic_memstream<char> memstream;
typedef basic_memstream<wchar_t> wmemstream;
}
#endif
分享到:
相关推荐
Abseil是由Google开源的一个C++库,包含了各种实用的工具和库,旨在提供跨平台、高质量的代码,用于实际的软件开发。Abseil的名称来源于“Abseiling”,在英文中意为“绳降”,象征着在编程中安全、稳健地下降到问题...
4. **结构体与联合体**:结构体允许将不同类型的数据组合成一个整体,联合体则是共享内存空间的结构。理解它们的使用场景和内存布局有助于优化数据结构。 5. **类与对象**:面向对象编程是C++的核心特性,包括类的...
该问题的基本设定是:一群人站成一个圆圈,按照顺时针方向从某个人开始报数,报到特定数值的人将被剔除出圈,然后从下一个人继续报数,直至只剩下最后一个人为止。在计算机领域,这个过程可以通过数据结构和算法来...
C++是一种强大的面向对象编程语言,它包含了封装、继承、多态等核心概念。...总的来说,这份模拟试题覆盖了C++的基础语法、类和对象、函数、运算符、内存管理等多个重要知识点,是学习C++过程中很好的练习材料。
- 通过 `malloc()` 分配内存来创建新的猴子节点,并将它们连接成一个环形链表。 - 在每次报数过程中,使用指针 `p` 和 `p2` 追踪当前节点和前一个节点,以便在猴子被淘汰时更新链表。 #### 3. 算法流程 - **初始...
在这个问题中,人们站成一个圆圈,并按顺序报数,每次数到特定数值的人会被排除出圈,然后从下一个人继续报数,直到只剩下最后一个人为止。这个最后幸存者的问题在计算机科学中常被用来研究算法和数据结构。 在这个...
结构体是C++中一种非常基础的构造,它允许程序员将多个不同的数据类型组合成一个单一的类型。在这个例子中,结构体 `A` 和 `B` 各自包含了一个名为 `a` 和 `b` 的数据成员,其类型为 `int`(整数类型),并且它们都...
在本项目中,"师生关系管理系统(C++)" 是一个基于C++编程语言开发的应用程序,其目标是管理和维护教育机构中的师生信息。这个系统利用线性表数据结构来存储和处理师生之间的关系,使得信息查询、添加、删除和更新等...
6. **读取文件**:使用文件流(fstream库)从stu.txt文件中读取学生信息,将每一项信息转化为一个节点,然后插入到链表中。 7. **输出信息**:同样使用文件流,将链表中的学生信息写回到文件,或者在控制台上打印...
7. **共用体(union)**:共用体允许在一个内存位置存储不同类型的成员,但同一时间只能访问其中一个成员。在这种情况下,`g.i` 的值影响了 `g.s` 的内存区域。 8. **this 指针**:每个对象都有一个隐含的 this ...
本案例中的“C++指针式时钟的设计”就是一个典型的示例,它要求我们利用C++编程语言来实现一个模拟指针式时钟的功能。以下是对这个项目涉及的知识点的详细解释: 1. **C++基础知识**:C++是一种静态类型的、编译式...
2. **引用**:引用是C++中的一个特殊类型,它不是一个新的变量,而是对已有变量的一个别名。文件中有多个关于引用的子文件,如"2.1引用"、"2.2引用的注意事项"和"2.3引用做函数参数",这些都强调了引用的使用方式和...
如果是,则用一个全局枚举变量put来记录来前触点是两个输入端和一个输出端中哪一个。 我们看这个枚举类型: enum Myput { Input_1, Input_2, Output_1 }; 接下来用一个全局变量circlepoint来记录当前触点中心点。...
- **层次型数据库**将数据组织成一棵树形结构,其中每一个节点都有一个父节点(除了根节点外),这种模型在处理特定类型的数据关系时非常有效。 - **网络型数据库**与层次型类似,但允许一个节点有多个父节点,能够...
C++是C语言的一个扩展,增加了面向对象特性,使得游戏开发更加高效且模块化。C++中的“类”是其核心概念,它允许开发者创建自定义的数据结构和行为,从而更好地模拟现实世界中的实体和过程。 在C++中,游戏编程的...
6. **结构与联合**: 结构体允许将不同类型的变量组合成一个单一的实体,而联合则允许一个变量在不同的时间表示不同的数据类型。 7. **预处理器**: 预处理器指令如#include、define和宏定义在编译阶段执行,用于文件...
在`Init_single_chain`函数中,通过循环创建`n`个节点,并将它们连接成一个环形链表。`Init_num`函数则负责给每个节点赋值其对应的编号。 ##### 4. 执行约瑟夫环算法 ```cpp void display(int n, int m) { // ...
场景是一个完整的屏幕视图,而层则是场景中的一个可独立管理的部分,多个层可以组合成一个场景。 2. **精灵(Sprite)与动画**:精灵是游戏中基本的可视元素,可以是角色、道具等。Cocos2d-x提供了精灵动画的支持,...
6. 结构类型数据:结构类型允许将多个不同类型的数据组合成一个新类型,方便处理复杂的数据结构,如学生信息、日期等。在需要处理多个相关数据项时,使用结构类型可以提高代码的组织性和可读性。 7. 定义和初始化...
- 将最后一个节点的`next`指针指向头节点的下一个节点,形成循环链表。 3. **模拟淘汰过程**: - 输入第一个报数者的密码初值。 - 循环执行以下步骤直至链表为空: - 当前节点`p`与其下一个节点进行比较,直到`...