您的位置:首页 > 编程语言 > C语言/C++

打造 C++ 最灵活动态数组结构 (二)

2008-07-01 11:42 232 查看
第二版代码如下:

1 MyData.h

/*--------------------------------*/

C++ 散列化数组结构

cjxxstar@gmail.com

cjxx 2008-06-27

/*--------------------------------*/

#ifndef __CJ_MY_DATA_H__

#define __CJ_MY_DATA_H__

#include <iostream>

#include <string>

#include <map>

using namespace std;

// 数字索引字符前缀

#define INT_INDEX_PRO_STR		"INT_INDEX_"

//	相关头信息

class MyData;

//	序列化时的风格类型

enum PRINT_R_STYLE {

PHP,JS

};

//	序列化一个字串到MyData

MyData& Serialize(const char* serStr, MyData* dVal = NULL);

//	反序列化一个MyData到 字符串

bool UnSerialize(MyData* dVal, string& unserStr);

//	格式化输出一个MyData 结构 -- 调试用

void print_r(MyData& data);

//	构造MyData 格式化字串

string& print_s(MyData& data,  string& str, bool bFormat = false, enum PRINT_R_STYLE style = PHP, int level = 0) ;

//	递归遍历 MyData 并执行用户自定义函数

void ForEachData(MyData& data, void* pCallBackFunc);

class MyData {

public:

enum ENUM_DATA_TYPE {

DATA_TYPE_DEF = 0,  // 初始类型

DATA_TYPE_DAT = 1,	// 数组类型

DATA_TYPE_INT = 2,  // 整数类型

DATA_TYPE_STR = 3,  // 字符类型

};

typedef map<string, MyData>  MAP_MY_DATA;

public:

// 构造

MyData() {

this->Init();

}

// 序列化构造

MyData(const char* dVal) {

this->Init();

Serialize(dVal, this);

}

// 析构

~MyData() {

this->Clear();

}

// 判断类型

bool IsType(enum ENUM_DATA_TYPE eType) {

return m_cType == eType;

}

// 获取类型

enum ENUM_DATA_TYPE Type() {

return m_cType;

}

// 获取MAP

MAP_MY_DATA& Map() {

return m_mapMyData;

}

// 获取整形数据

int i() {

return (m_cType == DATA_TYPE_INT) ? m_intData : 0;

}

// 获取字符数据

const char* c() {

return (m_cType == DATA_TYPE_STR) ? m_strData.c_str() : "";

}

// 获取反序列化字串

const char* u() {

m_strUnSer = "";

return UnSerialize(this, m_strUnSer) ? m_strUnSer.c_str() : "";

}

// 赋值为整数

void operator=(int iVal) {

this->Clear();

m_intData = iVal;

m_cType = DATA_TYPE_INT;

this->SetFatherDat();

}

// 赋值为字符

void operator=(const char* cVal) {

this->Clear();

m_strData = cVal;

m_cType = DATA_TYPE_STR;

this->SetFatherDat();

}

// 赋值为数据

void operator=(const MyData& dVal) {

this->Clear();

m_strData	= dVal.m_strData;

m_strUnSer	= dVal.m_strUnSer;

m_intData	= dVal.m_intData;

m_iNowIndex	= dVal.m_iNowIndex;

m_mapMyData	= dVal.m_mapMyData;

m_cType		= dVal.m_cType;

this->SetFatherDat();

}

// 自动增加一个数字索引

MyData& operator()() {

m_iTmpIndex = m_iNowIndex;

return this->Get(StrIndex(m_iNowIndex++));

}

// 整形索引

MyData& operator[](int keyName) {

m_iTmpIndex = keyName;

return this->Get(StrIndex(keyName));

}

// 字符型索引

MyData& operator[](const char* keyName) {

m_iTmpIndex = 0;

return this->Get(keyName);

}

// 自动转换成 int

operator int() {

return m_intData;

}

// 自动转换成 const char*

operator const char*() {

return m_strData.c_str();

}

private:

void Clear() {

if (m_cType == DATA_TYPE_DAT) {

m_mapMyData.clear();

}

}

void Init() {

m_iNowIndex = 0;

m_iTmpIndex = 0;

m_intData	= 0;

m_pFather	= NULL;

m_cType		= DATA_TYPE_DEF;

m_mapMyData.clear();

}

const char* StrIndex(unsigned int index) {

char buf[64] = {0};

sprintf_s(buf, INT_INDEX_PRO_STR"%d", index);

m_strUnSer = buf;

return m_strUnSer.c_str();

}

MyData& Get(const char* keyName) {

MAP_MY_DATA::iterator iter;

if (NULL == keyName) {

iter = m_mapMyData.find("");

} else {

iter = m_mapMyData.find(keyName);

}

if (iter != m_mapMyData.end()) {

return (*iter).second;

} else {

pair<MAP_MY_DATA::iterator, bool> Insert_Pair;

MyData data;

if (NULL == keyName) {

Insert_Pair = m_mapMyData.insert(MAP_MY_DATA::value_type("", data));

} else {

Insert_Pair = m_mapMyData.insert(MAP_MY_DATA::value_type(keyName, data));

}

(*Insert_Pair.first).second.SetFather(this);

return (*Insert_Pair.first).second;

}

}

void SetFatherDat() {

if (NULL != this->GetFather()) {

if (! this->GetFather()->IsType(DATA_TYPE_DAT)) {

this->GetFather()->m_cType = DATA_TYPE_DAT;

}

if (this->GetFather()->m_iNowIndex  < this->GetFather()->m_iTmpIndex) {

this->GetFather()->m_iNowIndex = this->GetFather()->m_iTmpIndex + 1;

}

this->GetFather()->SetFatherDat();

}

}

void SetFather(MyData* pData) {

m_pFather = pData;

}

MyData* GetFather() {

return m_pFather;

}

private:

enum ENUM_DATA_TYPE		m_cType;

string  				m_strData;

string  				m_strUnSer;

int 					m_intData;

int						m_iNowIndex;

int						m_iTmpIndex;

MyData*					m_pFather;

MAP_MY_DATA				m_mapMyData;

};

#endif //	end define __CJ_MY_DATA_H__

2 MyData.cpp

#include "MyData.h"

//	序列化成数据

MyData& Serialize(const char* serStr, MyData* dVal /*= NULL*/) {

MyData* pDVal;

if (dVal == NULL) {

pDVal = new MyData;

} else {

pDVal = dVal;

}

// 序列化并添加数据

return (*pDVal);

}

//	反序列化为字串

bool UnSerialize(MyData* dVal, string& unserStr) {

if (NULL == dVal) {

return false;

}

string str = "";

if (dVal->IsType(MyData::DATA_TYPE_DAT)) {

str += "{";

}

print_s(*dVal, str, false, JS, 0);

if (dVal->IsType(MyData::DATA_TYPE_DAT)) {

str += "}";

}

unserStr = str;

return true;

}

string& print_s(MyData& data,  string& str, bool bFormat /*= false*/, enum PRINT_R_STYLE style /*= PHP*/, int level /*= 0*/) {

char p_style[5][15] = {" =>array (", ")", "=>", "/"", ","};

char j_style[5][15] = {": {"       , "}", ":" , "/"", ","};

char (* u_style)[15] = style == PHP ? p_style : j_style;

string space = "";

if (bFormat) {

for (int i = 0; i < level; i++) {

space += " ";

}

++level;

}

if (data.IsType(MyData::DATA_TYPE_DAT)) {

MyData::MAP_MY_DATA::iterator iter = data.Map().begin();

for (;iter != data.Map().end();) {

string keyString = "";

if ((*iter).first.substr(0,strlen(INT_INDEX_PRO_STR)) == INT_INDEX_PRO_STR) {

keyString = (*iter).first.substr(strlen(INT_INDEX_PRO_STR), (*iter).first.length());

} else {

keyString+= u_style[3];

keyString+= (*iter).first.c_str();

keyString+= u_style[3];

}

if ((*iter).second.IsType(MyData::DATA_TYPE_DAT)) {

if (bFormat) {

str += space;

}

str += keyString;

str += u_style[0];

if (bFormat) {

str += "/n";

}

str  = print_s((*iter).second, str, bFormat, style, level);

if (bFormat) {

str += space;

}

str += u_style[1];

} else if ((*iter).second.IsType(MyData::DATA_TYPE_INT)) {

char buf[12] = {0};

sprintf_s(buf, "%d", (*iter).second.i());

if (bFormat) {

str += space;

}

str += keyString;

str += u_style[2];

str += buf;

} else if ((*iter).second.IsType(MyData::DATA_TYPE_STR)) {

if (bFormat) {

str += space;

}

str += keyString;

str += u_style[2];

str += (*iter).second.c();

}

if (++iter != data.Map().end()) {

str += u_style[4];

}

if (bFormat) {

str += "/n";

}

}

} else if (data.IsType(MyData::DATA_TYPE_INT)) {

char buf[12] = {0};

sprintf_s(buf, "%d", data.i());

if (bFormat) {

str += space;

}

str += buf;

if (bFormat) {

str += "/n";

}

} else if (data.IsType(MyData::DATA_TYPE_STR)) {

if (bFormat) {

str += space;

}

str += data.c();

if (bFormat) {

str += "/n";

}

}

return str;

}

void print_r(MyData& data) {

string str = "/n{/n";

print_s(data, str, true, JS, 1);

str += "}";

printf("%s", str.c_str());

}

void ForEachData(MyData& data, void* pCallBackFunc) {

}

3 testMain.cpp

#include "MyData.h"

int main(void)

{

int i = 0;

MyData testData;

MyData testData2("[1:22, '2':0, 'dff': [1:3]]");

testData[0]			= 100;

testData[1]			= "abc";

testData[3]			= 3;

testData[1]			= 1;

testData[6]			= 2;

testData()[1]		= 41;

testData[5]()[6]	= 506;

testData[5]["a"][1]	= 501;

testData[5][3][1]	= 511;

testData[5]()[2]	= 541;

testData["a"]()		= Serialize("[1:22, '2':0, 'dff': [1:3]]");

testData["a"]		= "fuck";

testData["a"][2]	= "a";

testData["a"]()		= "b";

testData["a"]()		= "c";

testData2[1]		= "abc";

testData2[2]		= 3;

testData2[3]()		= 4;

testData["c"]()		= 1;

testData["c"]()		= testData2;

testData[2][i][i]	= 2;

int b = testData[0];

const char* p = testData[1];

printf("%d/n", b);

printf("%s/n", p);

print_r(testData);

printf("%s", testData.u());

getchar();

return 1;

}

功能:
1 增加了类型自动识别转换的操作,这个功能需要依赖C++的编译器而不是用户逻辑,使用时小心。
2 增加反序列化功能,此功能可以将自身导出成字串用来存储发送,目前两种可选方案 -- JSON -- PHP方式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: