c++ - 如何更改静态链接库中 const 字符串数组的 Visual Studio C++ 初始化顺序

标签 c++ visual-studio visual-c++ visual-studio-2013

我正在 Visual Studio 2013 中对使用旧静态链接库的旧应用程序 (CWinApp) 进行一些更改。我在应用程序中初始化常量字符串数组时遇到问题。

为了让事情变得更容易,我创建了一个基本示例来演示该问题。该示例由引用静态库 MyLib.lib 的 CWinApp 应用程序(类 CTestApp)组成。 CTestApp 拥有一个在 MyLib 中定义的 MyClass 类型的对象。以下是一些代码摘录:

主应用程序(CTestApp)

TestApp.h:

class CTestApp : public CWinApp
{
   // --- Standard Wizard generated CWinApp stuff here ---
private:
   MyClass mine;
};

TestApp.cpp:

// --- Standard Wizard generated CWinApp stuff here ---

CTestApp::CTestApp()
   : mine(55)
{
}

静态库(MyLib.lib)

MyClass.h:

#pragma once

#include <string>

const std::string ids[] =
{
   "ABC",
   "DEF",
   "GHI"
};
const int num_ids = 3;

class MyClass
{
public:
   MyClass(int id);
private:
   int id;
   std::string name;
};

MyClass.cpp:

#include "MyClass.h"

MyClass::MyClass(int id)
: id(id)
{
   for (int i = 0; i < num_ids; ++i)
   {
      name += ids[i];
   }
}

问题是,当通过 CTestApp::CTestApp 进入 MyClass::MyClass 时,我发现数组 ids 中的字符串是空的。同样奇怪的是,整数常量 num_ids 按预期初始化为 3。这似乎只发生在静态库中声明的 const 字符串数组中。如果我在 CTestApp 本身中声明一个类似的数组,那么它会在我进入 CTestApp::CTestApp 时初始化。

我还发现,如果我运行应用程序并中断 CTestApp::InitInstance ,则 ids 已正确初始化。

有没有办法强制 Visual Studio 在进入 CTestApp::CTestApp 的成员初始化部分之前初始化此类常量字符串数组?

最佳答案

不是真的。不过,您也许可以解决您的具体情况。

ids 是动态初始化的全局变量。

您的全局 CTestApp 对象也是如此。

ids 在包含 header 的所有位置定义。 app 对象可能是在某个主文件中定义的。

C++ 未指定不同模块(.cpp 文件)中全局变量动态初始化的顺序。不同的编译、不同的编译器它可能有所不同。您不想依赖它。

如果需要保证顺序,唯一的办法就是将初始化放在同一个模块中。单个模块按照声明的顺序进行初始化。

因此,针对您的具体情况的解决方案是:在 header 中将 ids 声明为 extern,并实际将其与您的全局 app 一起定义,就在之前。但是,这不会随着您获得更多类(class)而扩展。

或者,将 ids 更改为 const char* 数组,使其成为真正的常量。这将使其静态初始化,这发生在动态初始化之前。

最后,您可以将 mine 更改为(智能)指针,并仅在 InitInstance 中初始化它。

关于c++ - 如何更改静态链接库中 const 字符串数组的 Visual Studio C++ 初始化顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21988793/

相关文章:

macos - 我无法通过 visual studio for Mac 安装教程的 remotebuild 部分

C++,如何找到成员函数的地址?

C++ 和 Lua - 尝试索引 nil 值错误

c++ - 使用 OpenCV 计算硬币

c++ - 密集对称矩阵的特征有效类型

c++ - 以秒为单位计算年龄的程序无法正常工作

c++ - GoogleTest Framework 似乎不适用于 Lambda 函数(跟进)

c# - 您如何从C#中以编程方式调用 “Document Format”?

c++ - 'wsprintfW' : cannot convert parameter 1 from 'char [80]' to 'LPWSTR'

visual-studio-2010 - 如何设置 nvcc 以使用来自 Windows SDK 7.1 的 Visual C++ Express 2010 x64?