共初始化()和静态混淆
coinitialize() and static confusion
我遇到了一个静态const类成员的情况,它调用一个静态函数来初始化它的值:
//A.h
class A
{
public:
static const int NUM;
static int Function();
};
//A.cpp
const int A::NUM = A::Function();
问题是A::Function()有一个本地静态变量,需要通过调用CoInitialize():来初始化COM库
//A.cpp
int A::Function()
{
static vartype m;
if(SUCCEEDED(CoInitialize(NULL)))
//Now m can be used and initialized.
// m.CreateInstance....
}
我以前在WinMain:中调用过CoInitialize()
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
{
if(SUCCEEDED(CoInitialize(NULL)))
{
MyApp* app = new MyApp;
app->Run();
delete app;
CoUninitialize();
}
return 0;
}
但是,由于ConInitialize()是在对A::Function()的调用中初始化静态成员变量A::NUM时调用的,并且这将在WinMain中的代码执行之前发生,我想我可以将其从我的WinMain:中删除
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
{
//if(SUCCEEDED(CoInitialize(NULL)))
{
MyApp* app = new MyApp;
app->Run();
CoUninitialize();
}
return 0;
}
现在这个程序运行得很好,但当我退出时,它会因访问违规而崩溃。有人能解释一下为什么会发生这种情况吗?
EDIT:我认为,由于静态变量应该在程序期间保持不变,所以当我调用CoUninitialize()时,本地静态变量m(需要COM库)会遇到问题。崩溃似乎与这个局部变量m有关。但问题是,我什么时候可以为需要COM库的静态变量调用CoUninitialize()?如果我在WinMain中取消注释if语句,问题似乎会消失,但我认为这是因为我最终调用了两次CoInitialize(),只调用了一次CoUninitialize()。
首先,您可以在这种情况下使用RAII。只需定义一个简单的类,如下所示:
class com_scope
{
com_scope(com_scope const&);
com_scope& operator= (com_scope const&);
public:
com_scope()
{
::CoInitialize(NULL);
}
com_scope(DWORD dwCo)
{
::CoInitializeEx(NULL, dwCo);
}
virtual ~com_scope() throw()
{
::CoUninitialize();
}
}
然后定义一个静态const com_scope_AppComScope。报表之前
const int A::NUM = ...
此代码将在第一次调用A::函数之前初始化COM环境,并在执行结束时进行清理。
您的问题极有可能是在使用某些COM引用之前破坏了COM环境。这解释了当您从WinMain中删除::CoUnitialize时,问题就会消失的事实。
p.S.
虽然这是个坏主意,但你可能不会在主线程中调用::CoUninitialize,因为当你的程序完成时,操作系统会进行清理
p.S.S.
此外,我必须承认,应该在CPP文件中定义_AppComScope,在该文件中为a::NUM分配一个值。否则,标准不能保证初始化的顺序
- 使用g++静态初始化带有命名标签的嵌套C++结构
- 静态初始化的反义词是什么?
- 在静态初始化期间运行代码
- 结构数组的嵌入式C++静态初始化
- 初始化与类类型相同的静态成员(静态初始化顺序问题)
- 使用 constexpr 和 std::array 进行静态初始化来替换动态初始化的 std::vector 的闰年
- MSVC 2017 在单个翻译单元中违反静态初始化顺序
- VC++6 线程安全静态初始化
- 具有必要副作用的静态初始化被优化掉了
- 未使用全球的静态初始化器
- w/ w/结构带char缓冲液的静态初始化[]
- 静态初始化的对象不能放在块中尝试
- 功能指针的静态初始化
- lambda(或函数)C++中的静态初始化
- C++静态初始化顺序:添加到映射中
- 复杂类型数组的静态初始化
- C++ - 在派生类中静态初始化受基类保护的成员变量
- 静态初始化插件工厂
- 静态初始化包含功能指针的对象的constexpr std ::数组
- 找出静态初始化是否结束