假设我有一个类,其唯一目的是在构造对象时产生的副作用(例如,使用工厂注册类):
class SideEffectCauser {
public:
SideEffectCauser() { /* code causing side-effects */ }
};
Run Code Online (Sandbox Code Playgroud)
还假设我想让一个对象为每个翻译单元创建一次这样的副作用.对于每个这样的翻译单元,我希望能够SideEffectCauser
在.cpp文件中的命名空间范围内放置一个对象,例如,
SideEffectCauser dummyGlobal;
Run Code Online (Sandbox Code Playgroud)
但C++标准03 3.6.2/3表明,此对象不必在所有的构造,除非使用在.cpp文件中的对象或功能,如文章这和网上的讨论,如这表明,这种对象有时不会被初始化.
另一方面,有没有办法从持有类名的字符串中实例化对象?有一个声称工作的解决方案,我注意到它基于使用类型的对象,SideEffectCauser
如静态数据成员,而不是全局,例如,
class Holder {
static SideEffectHolder dummyInClass;
};
SideEffectHolder Holder::dummyInClass;
Run Code Online (Sandbox Code Playgroud)
两个dummyGlobal
和dummyInClass
是非本地静态的,但在C++ 03标准的3.6.2/3细看表明,该通道仅适用于对象在命名空间范围.我实际上无法在C++ 03标准中找到任何内容,即当类范围内的非局部静态动态被动态初始化时,尽管9.4.2/7表明相同的规则适用于它们与命名空间中的非局部静态范围.
问题1:在C++ 03中,有没有理由相信它dummyInClass
更有可能被初始化dummyGlobal
?或者,如果同一翻译单元中没有使用任何功能或对象,可能都会未初始化?
问题2:C++ 11中有什么变化吗?3.6.2和9.4.2中的措辞与C++ 03版本不同,但据我所知,上面描述的场景没有指定行为差异.
问题3:是否有一种可靠的方法来使用类SideEffectHolder
功能体外的类对象来强制发生副作用?
我在 Linux 下使用与 g++ / C++11 类似的东西,并按预期注册我的工厂。我不确定为什么你不会调用这些函数。如果要实现您所描述的内容,则意味着该单元中的每个函数都必须调用初始化函数。我不太确定如何做到这一点。我的工厂也在命名空间内,尽管它被命名为命名空间。但我不明白为什么它不会被调用。
namespace snap {
namespace plugin_name {
class plugin_name_factory {
public:
plugin_name_factory() { plugin_register(this, name); }
...
} g_plugin_name_factory;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,无论如何,在 C++ 中不应再使用 static 关键字。静态定义通常比全局定义慢。
归档时间: |
|
查看次数: |
1371 次 |
最近记录: |