我有几个构建到静态库的模块。根据需要,可能会链接某些静态库,而其他静态库可能不会链接。其中一些静态库具有静态Init()方法的类。 “Core”库也链接在一起,也有一个Init()方法,之前它包含多行,如:
Telephony::Init();
但是如果Telephony不会被链接到这个特定的应用程序,我不想修改Core库的代码来删除该行。所以我尝试了类似的东西:
class init_hook_base
{
public:
inline init_hook_base() { Core::AddInitHook(this); }
protected:
friend class Core;
virtual ~init_hook_base() {}
virtual void operator()() const = 0;
};
template<class T>
class init_hook_t
{
protected:
void operator()() const
{
T::Init();
}
};
然后我会创建一个静态全局变量,如:
static init_hook_t<Telephony> telephony_init_hook;
在Telephony库中,这将允许Core在编译时间接调用Telephony :: Init而不知道它。不幸的是,telephony_init_hook没有构建,我假设它在链接阶段被剥离,尽管它的构造函数有副作用。做类似的事情:
void Telephony::Init() { (void)telephony_init_hook; }
同样不起作用,因为就链接器而言,Init本身也是无法访问的。有没有办法用C ++实现这种模块化风格?编译器特定的选项是可行的,只要GCC和VC ++都是等价的。感谢。
注意:对于那些关注影响Core :: AddInitHook的全局初始化顺序的人:
std::vector<init_hook_base*>* Core::init_hooks; //THESE ARE DELIBERATELY UNINITIALIZED!!!
unsigned char Core::init_hooks_ptr_hash[20];
bool Core::inited = false;
void Core::EnsureInitHooksContainerReady()
{
unsigned char current_hash[20];
sha1::calc(&init_hooks, sizeof(init_hooks), current_hash);
if (memcmp(current_hash, init_hooks_ptr_hash, 20))
{
//the hash is incorrect, so init_hooks is not yet initialized;
init_hooks = new std::vector<init_hook_base*>();
sha1::calc(&init_hooks, sizeof(init_hooks), init_hooks_ptr_hash);
}
}
void Core::AddInitHook(init_hook_base* init_hook)
{
EnsureInitHooksContainerReady();
init_hooks->push_back(init_hook);
}
void Core::Init()
{
assert(!inited);
PlatformInit();
EnsureInitHooksContainerReady();
for (auto init_hook_base : *init_hooks) {
(*init_hook_base)();
}
}
答案 0 :(得分:1)
您需要从init_hook_base继承init_hook_t。 就像现在一样,基类构造函数不会被调用。
答案 1 :(得分:0)