本文主要介绍一下如何使用c++设计成员变量可动态调整的抽象动态类结构。首先介绍一下项目中以前使用的一种类结构:静态类结构

  1.静态类结构

  很多时候,在项目开发中设计类结构时,我们往往有一种简单、直接的惯性思维:原始数据是什么样子,设计中类成员就包含相应的成员变量,这样的类我把它称之为静态类结构。静态类结构有两个特点。

  1.1特点一:类结构抽象能力不足。

   静态类结构强依赖于原始数据,是针对具体编程而不是针对抽象编程。一旦原始资源新增或者删除字段,类结构就要相应的调整类成员变量,费事费力,而且是重复机械的无技术含量的劳动。例如:影视资源video.json,其内容如下:

清单1: video.json

{"id":"","name":"黄飞鸿之英雄有梦",,"isenabled":,人","hotlevel":0,"source":0,"director":"周显扬"}

  针对该资源设计的静态类VideoRecord结构: 

清单2: class VideoRecord

 class VideoRecord
{
public:
INT hot;
INT hotlevel;
INT source;
INT isenable;
string id;
string name;
string director;
......
}

  假如现在video.json中新增字段copyright,videoRecord类就要增加相应的成员变量m_copyright。示例如下:

  1.2 特点二:类结构泛化能力不足

    一旦新增数据资源(例如:chanel.json),要么重新为该资源channel.json添加一个新的类结构ChannelRecord,要么合并channel.json和video.json中的所有字段,在原有VideoRecord类上新增成员。不管怎样做,面对时常变化的需求,你可能会产生这样直观的感受:这样的代码抽象和泛化能力太弱了。

    那么,能不能设计一种类结构,能够很好的解决静态类结构存在的所有问题,无论以后新增或者删除一个字段,或者新增或删除一种资源,都不必在让我们为此花费时间和心思呢?为此,需要在设计类上面花点心思,下面轮到动态类结构粉墨登场了。

  2.动态类结构

    只需要做几个改变,我们就能实现成员类型、个数等可动态伸缩调整的动态类结构啦。第一:重新设计类结构,定义指向所有的成员变量的指针的指针m_ppMember,可以通过m_ppMember访问到所有指向成员变量的指针。

     第二:有了m_ppMember指向所有的成员变量的指针,那么变量的个数和类型如何得知呢?这里就需要一个配置文件,指明资源中有多少字段,每个字段是什么类型。此外还需要记录描述表,每种资源都会产生一个独立的记录描述表,记录描述表通过读取配置文件生成,供动态类结构使用,因此记录描述表是动态类结构和配置文件的桥梁。由于Record并不含有成员变量类型等描述信息,Record对象的序列化和反序列化,必须借助m_type找寻到相应的记录控制表,才能完成。

    清单3:配置文件 config.json  

"video":
[
{"field":"name","type":"string"},
{"field":"id","type":"string"},
{"field":"actor","type":"string"}, //演员
{"field":"hot","type":"int"},
{"field":"hotLevel","type":"int"}
....... //其他字段,省略
]
 "channel":
[
{"field":"name","type":"string"},
{"field":"id","type":"string"},
{"field":"comment","type":"string"}, //评论
{"field":"hot","type":"int"},
....... //其他字段,省略
]

    清单4:记录控制表 class recCtrlTable

 #typedef string FIELD
#typedef int TYPE
2 #typedef int POS
class RecCtrlTable
{
private:
std::map<FIELD,std::pair<TYPE,POS>>m_recDes; //记录控制表会根据config.json的配置,把每个field及其类型、位置,记录在m_recDes中,供动态类Record使用
......
};

  3.生成动态类对象

上面讲述了如何设计动态类结构。有了动态类结构后,我们应该怎么使用该类生成一个类对象呢?举个例子:还是使用上面的video.json,以其中的director,name和hot字段段:

   (1)程序运行时首先加载config.json,生成RecCtrlTable类对象m_recCtrlTable对象;

(2)根据m_recCtrlTable中的m_recDes中的field,读入video资源相应feild字段,并申请内存pChar1...pCharN,存放该field的值;

(3)最后把这些指针pChar1...pCharN的首地址赋值给动态Record对象中的m_ppMember;

    从以上描述可以看出,每个Record类对象只记录该对象的资源类型m_type和成员变量值的指针,Record对象的成员变量值的写入和读取,需要依赖于记录控制表,这样做,虽然增加了实现的复杂度,但是节约很大一部分内存。

c++设计成员变量可动态调整的动态类结构的更多相关文章

  1. Objective-C类成员变量深度剖析

    目录 Non Fragile ivars 为什么Non Fragile ivars很关键 如何寻址类成员变量 真正的“如何寻址类成员变量” Non Fragile ivars布局调整 为什么Objec ...

  2. Objective-C类成员变量深度剖析--oc对象内存模型

    目录 Non Fragile ivars 为什么Non Fragile ivars很关键 如何寻址类成员变量 真正的“如何寻址类成员变量” Non Fragile ivars布局调整 为什么Objec ...

  3. C++构造函数和析构函数,以及构造函数特殊成员变量和函数的初始化

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  4. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

  5. Java bean 链式获取成员变量无需判空的工具设计

    Java bean 链式获取成员变量无需判空的工具设计 本篇文章已发布至公众号 Hollis 对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者 ...

  6. 测试 Java 类的非公有成员变量和方法

    引言 对于软件开发人员来说,单元测试是一项必不可少的工作.它既可以验证程序的有效性,又可以在程序出现 BUG 的时候,帮助开发人员快速的定位问题所在.但是,在写单元测试的过程中,开发人员经常要访问类的 ...

  7. CFormView动态调整对话框的尺寸和调整比例控制的部署

    基于单个文件CFormView动态调整对话框的尺寸和调整比例控制的部署 假设你正在开发一个程序基于单个文件,使用CFormView基类来实现多种形式展示,那么,这个文件可能会给你一点帮助. 一.实现对 ...

  8. juc线程池原理(二):ThreadPoolExecutor的成员变量介绍

    概要 线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析ThreadPoolExecutor类,来了解线程池的原理. ThreadPoolExecutor数据结构 Thread ...

  9. 动态线程池(DynamicTp)之动态调整Tomcat、Jetty、Undertow线程池参数篇

    大家好,这篇文章我们来介绍下动态线程池框架(DynamicTp)的adapter模块,上篇文章也大概介绍过了,该模块主要是用来适配一些第三方组件的线程池管理,让第三方组件内置的线程池也能享受到动态参数 ...

随机推荐

  1. http服务搭建

    http服务器搭建 主配置文件在 /etc/httpd/conf/httpd.conf 安装http  yum install httpd -y 启动http服务器  systemctl start ...

  2. Jsp注册界面——request对象

    1. Reg.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pa ...

  3. SQL Server 2008R2 企业版 百度云下载地址

    SQL Server 2008R2 (百度云下载地址:链接: http://pan.baidu.com/s/1mi34II8 密码: yc1w)   ASP.NET MVC4.0+ WebAPI+Ea ...

  4. golang中的reflect包用法

    最近在写一个自动生成api文档的功能,用到了reflect包来给结构体赋值,给空数组新增一个元素,这样只要定义一个input结构体和一个output的结构体,并填写一些相关tag信息,就能使用程序来生 ...

  5. canvas随笔

    公司刚刚处于创业初期,总是会尝试着做一些新奇的东西.尤其是对于网上一些好玩的东西,总是希望自己也能有一样的功能.不得不说,对于我来说,既是种机遇,也是种挑战.因为这样给了我足够的发展空间,可以按着自己 ...

  6. Linked List Cycle && Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Note ...

  7. python实现视频下载

    最近一两年短视频业务风生水起,各个视频网站都有各自特色的短视频内容.如果有这样一个程序,可以把各大视频网站的热门用户最新发布的视频都下载下来,不仅方便自己观看,还可以将没有版权的视频发布在个人社交网站 ...

  8. 1651: [Usaco2006 Feb]Stall Reservations 专用牛棚

    1651: [Usaco2006 Feb]Stall Reservations 专用牛棚 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 566  Sol ...

  9. UNIX 网络编程知识,函数积累

    1: fprintf()#include <stdio.h> int fprintf( FILE *stream, const char *format, ... );fprintf()函 ...

  10. MySQL常用函数及日期

    一.数学函数 数学函数主要用于处理数字,包括整型.浮点数等. ABS(x) 返回x的绝对值 SELECT ABS(-1) -- 返回1 CEIL(x),CEILING(x) 返回大于或等于x的最小整数 ...