在第一次使用类构造函数时,我有一个类使用std :: call_once()和std :: once_flag来对类中的静态数据进行延迟初始化。因此,once_flag是类的静态成员。我的问题是,我不知道在主应用程序和应用程序在不同时间加载和卸载的各种DLL之间共享此方法的最佳方法。
我唯一的想法是让EXE版本的类导出std::once_flag *GetOnceFlag()
,它返回静态once_flag的地址,而DLL中的类将使用call_once()和GetOnceFlag(): MyClass::Myclass(void) { call_once(*GetOnceFlag(), &MyClass::Init, this); }
这种方法会起作用吗?
缺点是每次ctor都会调用GetOnceFlag(),这对于轻量级ctor来说是低效的(在我的情况下,除了调用call_once()之外什么都不做)。但是我不确定在MyClass::Myclass(void) { if (!_pflag) _pflag = GetOnceFlag(); call_once(*_pflag, &MyClass::Init, this); }
中缓存指针所暗示的竞争是否是一个问题(指针写入在我感兴趣的所有平台上都是原子的,所以如果同时调用GetOnceFlag(),我认为它应该没问题,但我不完全确定。)
欢迎提出意见和更好的解决方案。
编辑:我知道共享类可以放在其他人使用的单独的DLL中,但是这不会影响MSVC的整个程序优化/链接时代码生成吗?我假设/ GL和/ LTCG文档中提到的跨模块优化仅针对链接的单个对象和静态库,并且不能跨DLL边界发生。