我有应用程序单例,它有方法
void addHandler(const std::string& command, std::function<std::string (const std::string&)> handler)
我想用像这样的处理程序创建很多cpp文件
//create_user_handler.cpp
Application::getInstance()->addHandler("create_user", [](std::string name) {
UserPtr user = User::create(name);
return user->toJson();
});
如何从我的cpp文件中自动调用它?
我尝试从void addHandler
更改为bool addHandler
,然后使用
namespace {
bool b = Application::getInatance()->addHandler......
}
但它对我不起作用
UDATE 它现在有效,但是可以以更好的方式完成,没有未使用的bool变量吗?
答案 0 :(得分:2)
使用静态类实例化。
伪代码 - 添加一个registrator类。
class Registrator {
template <typename Func>
Registrator(const std::string& name, Func handler) {
Application::getInstance()->addHandler(name, handler);
}
};
在每个cpp文件中,创建一个静态类对象:
test.cpp
static Registrator test_cpp_reg("create_user", [](std::string name) {
UserPtr user = User::create(name);
return user->toJson();
});
答案 1 :(得分:1)
我认为addHandler()应该返回bool?否则,您无法分配给bool变量。
要删除addHandler的bool返回,请从静态实例化的其他类的构造函数中调用。
这种代码可以工作,但很棘手。问题是在C / C ++中,静态存储初始化器的顺序是未定义的。因此,虽然允许静态初始化程序调用任何代码,但如果该代码引用尚未初始化的数据,则它将失败。不幸的是,失败是不确定的。它可能会工作一段时间,然后你改变一些编译器标志或模块顺序,并splat!
一个技巧是使用哑指针实现getInstance()的实例状态,因为在任何静态初始化程序触发之前,它总是初始化为零(null)。例如,以下代码将在主要启动之前打印“Added foo”:
#include <string>
#include <functional>
#include <map>
#include <iostream>
class Application {
public:
static Application* getInstance() {
// Not thread-safe!
if (instance == 0) {
instance = new Application;
}
return instance;
}
typedef std::function<std::string(const std::string&)> HANDLER;
typedef std::map<std::string, HANDLER> HANDLER_MAP;
bool addHandler(const std::string& command, HANDLER handler) {
handlerMap.insert(HANDLER_MAP::value_type(command, handler));
std::cout << "Added " << command << "\n";
return true;
}
HANDLER_MAP handlerMap;
static Application* instance;
};
Application* Application::instance;
std::string myHandler(const std::string&) { return ""; }
bool b = Application::getInstance()->addHandler("foo", myHandler);
int main()
{
return 0;
}