C++ 自注册课程的替代方案
我的项目以两种方式使用自注册类:一种是实现工厂模式,它允许迭代此类的映射,实现几乎完全类似于中描述的实现;另一种是将巨大的switch语句分离成对象映射。在后一种情况下,我刚刚创建了一个基类和一组派生类,然后在源文件中用静态对象实例化了每个派生类,而类的构造函数在映射中注册它们自己 现在我尝试将我的应用程序的逻辑部分移动到静态库中,并在两个子项目中使用该库(我使用Qt、Qt Creator和gcc)。这样做之后,除非我在某个地方对这些类进行了明确的实例化,否则上述类都不能工作 所以,我正在寻找解决办法。实际上,另一个问题是:用C++自动注册技术来设计C++应用程序是不是一个很坏的内涵? 编辑:我被要求举个例子。以下是简化代码:C++ 自注册课程的替代方案,c++,C++,我的项目以两种方式使用自注册类:一种是实现工厂模式,它允许迭代此类的映射,实现几乎完全类似于中描述的实现;另一种是将巨大的switch语句分离成对象映射。在后一种情况下,我刚刚创建了一个基类和一组派生类,然后在源文件中用静态对象实例化了每个派生类,而类的构造函数在映射中注册它们自己 现在我尝试将我的应用程序的逻辑部分移动到静态库中,并在两个子项目中使用该库(我使用Qt、Qt Creator和gcc)。这样做之后,除非我在某个地方对这些类进行了明确的实例化,否则上述类都不能工作 所以,我正在寻找解
// Class for storing actions
class ActionBase;
class SomeObject;
class ActionMap
{
public:
ActionMap();
static void registerAction(int n, ActionBase* action) {}
void performAction (SomeObject* object, int action) {
m_actions[action]->perform(object);
}
private:
std::map<int, ActionBase*> m_actions;
};
// Action class - action.h
#include "actionmap.h"
class SomeObject;
class ActionBase
{
public:
ActionBase(int n, ActionBase* action) {ActionMap::registerAction(n, action); }
virtual ~ActionBase() = 0;
virtual void perform(SomeObject* object) = 0;
};
template<int N>
class Action : public ActionBase
{
public:
Action() : ActionBase(N, this) {}
};
template<>
class Action<1> : public ActionBase
{
public:
Action() : ActionBase(1, this) {}
void perform(SomeObject* object)
{
// Do something
}
};
//用于存储操作的类
类操作库;
类对象;
类动作图
{
公众:
ActionMap();
静态无效注册表操作(intn,ActionBase*action){}
无效执行(SomeObject*对象,int操作){
m_actions[动作]->执行(对象);
}
私人:
映射m_动作;
};
//行动-集体行动
#包括“actionmap.h”
类对象;
类ActionBase
{
公众:
ActionBase(int n,ActionBase*action){ActionMap::registerAction(n,action);}
virtual~ActionBase()=0;
虚空执行(SomeObject*object)=0;
};
模板
集体诉讼:公共诉讼基础
{
公众:
Action():ActionBase(N,this){
};
模板
集体诉讼:公共诉讼基础
{
公众:
Action():ActionBase(1,this){}
执行void(SomeObject*对象)
{
//做点什么
}
};
现在我可以在actions源文件中创建一些action对象,例如:
// action.cpp
// #include "action.h"
static Action<1> action1;
//action.cpp
//#包括“action.h”
静态作用1;
重组项目后,我必须在子项目的某个地方显式地创建action1变量,以便能够使用它,例如在main.cpp中
更新:似乎Angew帮我部分解决了第二个问题。我已经清除了一个自由空函数,并在action.cpp中定义了它。在应用程序的某个地方调用它会强制初始化动作对象
用自注册技术设计C++应用程序是不是一个很不好的内涵?
恐怕我不得不对这个问题回答“是”。C++允许显式地允许非本地变量在main
的第一条语句之前完成。如果初始化延迟到某个时间点
在main
的第一条语句之后,应在任何函数或变量的第一次odr使用(3.2)之前发生
在与要初始化的变量相同的转换单元中定义
换句话说,文件中定义的全局变量(其初始化进行了一些注册)在调用该文件中的其他代码之前可能不会初始化(并因此注册)。“除非”您需要对此进行更多的解释,并尝试包含一个@RichardCritten,这很可能是链接器删除了包含注册实例的对象文件,因为没有人引用它。“如果你问我的话,那就是行为不检,但我们到了。”昆汀不一定。不要忘记,在C++中,文件范围变量只能在执行该文件的任何代码之前被初始化,但是在代码>主< /代码>开始后,它们可以被初始化。直到这实际上是明确的实现定义。。。对于静态注册对象来说,这是一个很糟糕的问题:/您的问题的解决方案如下所示: