zoukankan      html  css  js  c++  java
  • C++ 动态生成对象

    1、啰嗦一下

        说起C++,很多人都觉着难学,其实我也是这么觉着的,在这个移动端火到爆的时代,我都想改行了,移动端做东西那都是现有的第三方库,拿来就可以用,而且稳定性好,开发速度快,而且最关键的是出东西。

        在谈一谈动态生成对象,为什么强大的C++不支持呢?想用这样功能的人都必须自己实现一套这样的逻辑。

    2、实现理由

        有时候开发真是有些矛盾,例如:1、实现一个功能可以使用大量相似的代码、也可以使用模板,那我们怎么选择呢? 2、如果实现一个类之后,他有大量的属性,而且这些属性都需要set和get方法,那么我们还是要Ctrl +C和Ctrl+V吗?如果有好多这样的类,还是Ctrl+C和Ctrl+V吗?对于第一个问题,一个力求上进开发人员,我相信他会选择模板,第二个问题的答案,也就是我们这篇文章所需要讲到的东西,动态生成对象、序列化和反序列化。

    3、实现思路

        其实这个功能实现起来代码量还是比较少的,就是使用大量的宏和工厂模式

    1、写一个工厂类,专门用于生成对象

     1 typedef void * (* CreateClass)(void);
     2 
     3 class CClassFactory
     4 {
     5 public:
     6     static CClassFactory & IntanceFactory();
     7 
     8 public:
     9     void * CreateObject(const std::string & className);
    10     void RegistClass(const std::string & name, const CreateClass & method);
    11 
    12 private:
    13     std::map<std::string, CreateClass> m_classMap;
    14 };

    2、然后在写一个方便类,这个类仅仅是为了注册方便,当这个类被声明的时候,即注册一个类到工厂中

    1 class CDynamicClass
    2 {
    3 public:
    4     CDynamicClass(const std::string & name, const CreateClass & method)
    5     {
    6         CClassFactory::IntanceFactory().RegistClass(name, method);
    7     }
    8 };

    3、2个关键的宏,这两个宏一个是用于CDynamicClass静态对象的,一个是用于初始化CDynamicClass对象的,作用请看上一小节,呵呵呵,其实就是注册宏的参数类到工厂

    1 #define DECLARE_CLASS(className)
    2 std::string className##Name;
    3 static CDynamicClass * className##Namedc;
    4 
    5 #define IMPLEMENT_CLASS(className)
    6 CDynamicClass * className::className##Namedc = new CDynamicClass(#className, className::Instance);
    7 
    8 #define DESTORY_CLASS(className)
    9 if (className##Namedc){delete className##Namedc; className##Namedc = nullptr;}

    4、2个属性宏,ACCESS_INTERFACE宏用于注册属性的相关接口,ACCESS_REGISTER宏是把属性名字和对象的属性调用接口记录起来,方便以后设置属性

     1 #define ACCESS_INTERFACE(classType, type, name, describe)
     2 public:
     3     std::string m_Describe##name = #describe;
     4     inline static void Set##name(CBaseClass * cp, void * value){
     5         classType * tp = (classType *)cp;
     6         tp->m_##name = *(type *)value;
     7     }
     8     inline type Get##name(void) const {
     9         return m_##name;
    10     }
    11     inline std::string Get##name##Describe(){ 
    12         return m_Describe##name;
    13     }
    14 
    15 #define ACCESS_REGISTER(name)
    16     m_propertyMap.insert({ #name, Set##name });

    5、基类,所有对象的基类,m_propertyMap成员是存储属性和属性对于的set接口对

     1 class CBaseClass
     2 {
     3 public:
     4     CBaseClass() {}
     5     virtual ~CBaseClass() {}
     6 
     7 public:
     8     std::map<std::string, SetValueProperty> m_propertyMap;
     9 
    10 private:
    11 };

    4、测试类

     1 class CHelloClass : public CBaseClass
     2 {
     3 public:
     4     DECLARE_CLASS(CHelloClass);
     5     ACCESS_INTERFACE(CHelloClass, int, Age, "年龄")
     6     ACCESS_INTERFACE(CHelloClass, int, Sex, "性别")
     7 
     8 public:
     9     CHelloClass();
    10     virtual ~CHelloClass();
    11 
    12 public:
    13     static void * Instance();
    14     
    15 public:
    16     virtual void RegistProperty( );
    17 
    18 protected:
    19     int m_Age = 0;
    20     int m_Sex = 0;
    21 };

    CHelloClass类是一个测试类,用于测试第三节所写的动态生成对象是否正确,RegistProperty接口里边是对属性的注册

    1、测试main函数

     1 int main(int argc, char *argv[])
     2 {
     3     QCoreApplication a(argc, argv);
     4 
     5 
     6     CHelloClass * pVar = (CHelloClass*)CClassFactory::IntanceFactory().CreateObject("CHelloClass");
     7     if (pVar)
     8     {
     9         int pAge = 2;
    10         int pSex = 1;
    11 
    12         pVar->m_propertyMap["Age"](pVar, &pAge);
    13         pVar->m_propertyMap["Sex"](pVar, &pSex);
    14 
    15         std::cout << pVar->GetAgeDescribe() << pVar->GetAge() << std::endl;
    16         std::cout << pVar->GetSexDescribe() << pVar->GetSex() << std::endl;
    17     }
    18 
    19     return a.exec();
    20 }

    2、效果结果截图

    图1 CHelloClass测试结果

    5、序列化和反序列化

        本片文章主要讲解的是动态生成对象,并没有打算深入的去剖析系列化和反序列化的模块,demo中也有一小部分的序列化代码,主要是使用tinyxml2来读文件,代码如下:

     1 void DynamicObject::Deserialize()
     2 {
     3     tinyxml2::XMLDocument doc;
     4     if (tinyxml2::XML_NO_ERROR == doc.LoadFile("D:\example\paint\DynamicCreateObject\test.xml"))
     5     {
     6         if (tinyxml2::XMLNode * rootNode = doc.FirstChildElement("Ojbectlist"))
     7         {
     8             const char * rootText = rootNode->ToElement()->Attribute("name");
     9 
    10             tinyxml2::XMLElement * element = rootNode->FirstChildElement("Object");
    11             while (element)
    12             {
    13                 const char * objectName = element->Attribute("name");
    14                 tinyxml2::XMLElement * propertyElement = element->FirstChildElement("Property");
    15                 while (propertyElement)
    16                 {
    17                     const char * propertyName = propertyElement->Attribute("name");
    18                     const char * propertyValue = propertyElement->Attribute("value");
    19                 }
    20                 tinyxml2::XMLNode * nextNode = element->NextSibling();
    21                 if (nextNode == nullptr)
    22                 {
    23                     break;
    24                 }
    25                 element = nextNode->ToElement();
    26             }
    27         }
    28     }
    29 }

        说到对象序列化,我就觉得有一个问题比较难搞定,对象包含对象,也就是递归序列化,如果涉及到判断递归那么我们可能还需要自己实现一套结构,用于表示当前对象是否包含其他对象,是否需要继续递归序列化的问题。后面有机会我会对此问题在专门做一篇文章加以解释。

    6、demo下载地址

         C++动态生成对象

    如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!! 

     

      


    很重要--转载声明

    1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
    2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。 

  • 相关阅读:
    HDU 1010 Tempter of the Bone
    HDU 4421 Bit Magic(奇葩式解法)
    HDU 2614 Beat 深搜DFS
    HDU 1495 非常可乐 BFS 搜索
    Road to Cinema
    Sea Battle
    Interview with Oleg
    Spotlights
    Substring
    Dominating Patterns
  • 原文地址:https://www.cnblogs.com/swarmbees/p/6033666.html
Copyright © 2011-2022 走看看