如何控制各种类的静态成员对象的创建顺序?

问题描述

如何控制各种类的静态成员对象的创建顺序?

想用C++实现类似Java的反射机制,参考网上的设计方案形成了如下代码:
基类声明和实现:
protocolui.h:

#ifndef PROTOCOLUI_H
#define PROTOCOLUI_H

#include<map>
#include <string>

class UIProtocolDev;
struct UIProtocolDevInfo;
typedef UIProtocolDev* (*_tfnCreateUI) (void);

class UIProtocolDev
{
   static std::map<std::string, _tfnCreateUI> m_uiInfoMap;

public:
   UIProtocolDev() {}
   virtual ~UIProtocolDev() {}

   static bool registerUI(UIProtocolDevInfo* pUiDevInfo);
   static UIProtocolDev* CreateUI(std::string type);
};

struct UIProtocolDevInfo {
   std::string    _type;
   _tfnCreateUI   _fnCreateUI;
   UIProtocolDevInfo(std::string const type, _tfnCreateUI fnCreateUI);
};

#endif //PROTOCOLUI_H

protocolui.cpp

#include "protocolui.h"

std::map<std::string, _tfnCreateUI> UIProtocolDev::m_uiInfoMap;

bool UIProtocolDev::registerUI(UIProtocolDevInfo *pUiDevInfo)
{
   if (pUiDevInfo == NULL) return false;
   m_uiInfoMap[pUiDevInfo->_type] = pUiDevInfo->_fnCreateUI;
   return true;
}

UIProtocolDev *UIProtocolDev::CreateUI(std::string type/*, QObject *parent, logstream::ILogHost * const logHost, const char *strIdentifier*/)
{
   if (m_uiInfoMap[type] != NULL) {
      return m_uiInfoMap[type](/*parent, logHost, strIdentifier*/);
   }
   return NULL;
}

UIProtocolDevInfo::UIProtocolDevInfo(const std::string type, _tfnCreateUI fnCreateUI)
{
   _type = type;
   _fnCreateUI = fnCreateUI;
   UIProtocolDev::registerUI(this);
}

继承类声明和实现:
uiprotocolserialport.h:

#ifndef UIPROTOCOLSERIALPORT_H
#define UIPROTOCOLSERIALPORT_H

#include "protocolui.h"
#include <QObject>
#include <string>

class Test : public UIProtocolDev
{
public:
   Test() {}
   virtual ~Test() {}
   static UIProtocolDev* CreateUI(void)
   { return new Test(); }
private:
   static UIProtocolDevInfo m_devinfo;
};
#endif // UIPROTOCOLSERIALPORT_H

uiprotocolserialport.cpp:

#include "uiprotocolserialport.h"
UIProtocolDevInfo Test::m_devinfo("Test",(_tfnCreateUI)(Test::CreateUI()));

main.cpp:

void main(void)
{
    UIProtocolDev * pdev = UIProtocolDev::CreateUI("Test");
    delete pdev;
}

使用MinGW-w64 4.9.2编译链接后,运行时报告程序崩溃;
尝试将uiprotocolserialport.h和uiprotocolserialport.cpp中的代码分别移动到uiprotocol.h和uiprotocol.cpp中后,程序正常执行并正常结束。
由此怀疑在继承类与基类不在相同的文件中时,MinGW-w64的GCC编译器没有正确的安排基类静态成员变量UIProtocolDev::m_uiInfoMap和继承类静态成员变量Test::m_devinfo的创建顺序,使得继承类的静态成员先于基类的静态成员创建,但由于继承类的静态成员构造函数在执行时需要使用基类的静态成员,这造成访问未初始化内存区的错误。
因此,请问:
1.如何控制不同文件之间各种类的静态成员对象的创建顺序呢?
2.若无法控制创建顺序,有没有变通的办法来实现类似JAVA的反射机制呢?

解决方案

参考《深入浅出MFC》
MFC机制模拟之RTTI。

时间: 2024-11-01 10:24:34

如何控制各种类的静态成员对象的创建顺序?的相关文章

Spring使用静态工厂方法创建Bean

1. 使用静态工厂方法创建Bean     使用静态工厂方法创建Bean实例时,class属性也必须指定,但此时class属性并不是指定Bean实例的实现类,而是静态工厂类.因为Spring需要知道是用哪个工厂来创建Bean实例.另外,还需要使用factory-method来指定静态工厂方法名,Spring将调用静态工厂方法(可能包含一组参数),来返回一个Bean实例,一旦获得了指定Bean实例,Spring后面的处理步骤与采用普通方法创建Bean实例则完全一样.需要注意的是,当使用静态工厂方法

静态变量是有顺序的!

有人问过我,下面这个打印结果为什么是0public class MyClass{  private static int x = getValue();  private static int y = 5;  private static int getValue()  {    return y;  }  public static void main(String args[])  {   System.out.println(x);  }  } 在执行x初始化的时候,这个时候y并没有初始化

线性链表其他种类(静态,双向,循环)的存储结构和常见操作

一.静态单链表 在不支持动态空间分配的环境中,要使用链表存储数据,那么可采用静态链表的方法:即在一块预分配的存贮空间中,用下标作为指针链来构成链式结构. //既然是静态链表,那么可以使用一维数组实现存储,java没有指针,那么就用这来使用链表结构 //在不支持动态空间分配的环境中,要使用链式结构技术,可采用静态链表的方法:即在一块预分配的存贮空间中,用下标作为指针. //存储结构:在数组中增加一个"指针"域,存放下一元素在数组中的下标.且0为代表空指针   //设S为SLinkList

smarty 缓存控制前的页面静态化原理_php技巧

可在display中进行设置 $smarty->display("demo.tpl",$_SERVER[REQUEST_URI])来实现一个模版有多个缓存. 既然文件已经有缓存了,我们就可以走缓存文件了,不用循环的执行连接数据库,进行查询了.用smatry中的一个函数进行判断 $smarty->iscached(demo.tpl"",",$_SERVER[REQUEST_URI])默认值为"true" 这里的模版要和disp

C静态库连接的顺序问题

C语言的静态连接,简单的说就是将编译得到的目标文件.o(.obj),打包在一起,并修改目标文件中函数调用地址偏移量的过程.当在大一点的项目中,可能会遇到连接时,由于静态库在链接器命令行中出现顺序的问题,造成undefined reference错误.本文深入探讨一下这个问题,以及如何解决. 问题 如下图.假设有这么一个场景,在我们的构建系统中,构建了一个两个静态库文件liba.a和libb.a,其中liba.a包含两个目标文件a1.o和a2.o,而libb.a包含一个目标文件b1.o.希望将ma

Asp.net实现IIS控制管理(Web虚拟目录的创建及管理)

asp.net|iis|web|创建|控制|虚拟目录   (一)CreateWebDir.cs 使用示例 string sServer = "localhost";string VirtualDir = "Bug2004"; \\虚拟目录string PathDir = @"D:\myWebDirTest\Bug2000" \\物理目录 IISManager iisMg = new IISManager(sServer);iisMg.Connec

IIS控制管理(Web虚拟目录的创建及管理)

iis|web|创建|控制|虚拟目录 (一)CreateWebDir.cs 使用示例 string sServer = "localhost"; string VirtualDir = "Bug2004"; \\虚拟目录 string PathDir = @"D:\myWebDirTest\Bug2000" \\物理目录 IISManager iisMg = new IISManager(sServer); iisMg.Connect(); if

gcc中动态库和静态库的链接顺序

so文件:动态库a文件: 静态库exe文件:可执行程序(linux下以文件属性来标示是否是可执行文件,与后缀名无关) 经过自己写的一些测试程序,大致了解了下gcc中链接顺序问题,总结出以下几点:1,动态库中可以包含另一个静态库,通过参数 -lxxx 把静态库libxxx.a加入so文件中,这样so文件中   就包含了libxxx.a的所有实现.当然,如果不包含libxxx.a也没有问题,这样生成的so会小一点.   如果不包含libxxx.a,最终使用这个so的可执行文件,在其生成时必须加入 -

iOS中 Framework静态库的创建和使用遇到的那些坑 韩俊强的博客

前言 网上关于Framework制作的教程数不胜数,然而都过于陈旧,最新的也是使用Xcode7的教程,而且有些设置也只给出步骤,并没有给出原因,而且按照有些教程制作出的framework还有些问题,所以我把自己制作framework的过程记录下来,并且使用的是最新的Xcode8环境.本次制作framework,包含AFN,FMDB第三方,.a文件,xib,Bundle文件,还有Category分类,几乎制作和使用framework遇到的所有坑都被我遇到了,所以,此篇博客在我这属于干货,特此分享给