1 使用宏定义创建类的实例
#include <iostream>
#include <cstring>
#include <stdexcept>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <mutex>
#include <deque>
#include <thread>
#include <pthread.h>
#include <unistd.h>
#include <memory>
#include <condition_variable>
#include <future>
#include <list>
class Base {
public:
virtual void f() {
std::cout << "this is Base";
};
};
class A : public Base {
public:
void f() {
std::cout << "this is A";
}
};
typedef std::shared_ptr<Base> (*CreatefeedFunction)();
typedef std::unordered_map<std::string, CreatefeedFunction> feedMap;
feedMap g_feed_map;
#define REGISTER_DATAFEED_CLASS(feed_class) \
namespace { \
std::shared_ptr<Base> Creator_##feed_class() { \
return std::shared_ptr<Base>(new feed_class); \
} \
class __Registerer_##feed_class { \
public: \
__Registerer_##feed_class() { \
g_feed_map[#feed_class] = &Creator_##feed_class; \
} \
}; \
__Registerer_##feed_class g_registerer_##feed_class; \
} // namespace \
REGISTER_DATAFEED_CLASS(A); // 函数体内部不能进行函数的定义
int main()
{
std::shared_ptr<Base> p = g_feed_map["A"]();
p->f();
return 0;
}
上述代码中,定义了一个基类 Base,派生出类 A。同时,还定义了一个 key 为 string,value 为函数指针的哈希表(g_feed_map),该函数指针对应的功能就是创建类的实例,也就是 std::shared_ptr p = g_feed_map"A".
上述宏定义中, # 的功能是将其后面的宏参数进行字符串化操作,简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号。## 功能是在带参数的宏定义中将两个子串联接起来,从而形成一个新的子串。 但它不可以是第一个或者最后一个子串。新同学可能还不了解,特此解释下~
方法2:
此方法用的是static,在main函数执行之前就进行初始化。
出现的问题: 创建的类有依赖(在构造函数中调用了)运行时才会初始化的变量,因此出现了问题。
解:把依赖的部分移到运行时再初始化。
template <class T>
class Test {
public:
QSharedPointer<T> child;
Test(const QString& name) : child(new T) {
child->setObjectName(name);
TestRegister::registerTest(child.data());
}
};
#define REGISTER_TEST(class_name) static Test<class_name> t(#class_name);