我有很多 C# 代码必须用 C++ 编写。我在 C++ 方面没有太多经验。
我正在使用 Visual Studio 2012 进行构建。该项目是 C++ 中的静态库(不是 C++/CLI)。
我正在创建一些单元测试,在 C# 版本中,它们有一个类 TestData、一些 TestData 的static instaces 和一个static Initialize 方法,为这些静态实例设置值。
当我尝试在 C++ 中执行相同操作时,我发现如果我的 Initialize 方法是在 TestData 类中声明的,它就不起作用。但如果我在外面声明它,它就会起作用。
C++(测试)
TEST_CLASS(UnitTest1)
{
public:
TEST_CLASS_INITIALIZE(ClassInitialize)
{
TestData::Initialize();
}
TEST_METHOD(TestMethod1)
{
Assert::AreEqual(data0.testValue, 30);
}
};
C++(TestData 类中的 Initialize 方法):
测试失败并声明了 Initialize 方法。当我调试时,我看到正在设置 testValue,但当它到达时, Assets 又回到 0。
//.h
namespace Data
{
class TestData
{
public:
TestData(void);
~TestData(void);
int testValue;
static void Initialize();
};
static TestData data0 = TestData();
}
//.cpp
namespace Data
{
TestData::TestData(void){}
TestData::~TestData(void){}
void TestData::Initialize()
{
data0.testValue = 30;
}
}
C++(在类外声明的初始化方法):
有了这样的代码,我的测试就成功了。
//.h
namespace Data
{
class TestData
{
public:
TestData(void);
~TestData(void);
int testValue;
};
static TestData data0 = TestData();
static void Initialize()
{
data0.testValue = 30;
}
}
为什么会这样?
更新:
根据 Hans 的建议,我跟踪了正在使用的变量的地址。它帮助我注意到,出于某种原因,TestData 的构造函数被调用了两次。我不知道为什么。我想可能是调用了自动分配,所以我在构造函数中添加了一个 int 参数,看看会发生什么,它似乎调用了两次 data0 的构造函数。
当我的测试不起作用时(在类中有 Initialize),调用顺序是:
- TestData (data0) 构造函数(地址:1)
- TestData (data0) 构造函数(地址:2)
- 初始化:使用 data0 和 Address 1
- 测试:使用 data0 和 Address 2
当我的测试工作时(在类外初始化)调用顺序是:
- TestData (data0) 构造函数(地址:1)
- TestData (data0) 构造函数(地址:2)
- 初始化:使用 data0 和 Address 2
- 测试:使用 data0 和 Address 2
现在我明白了为什么我的测试失败了。但我不明白为什么构造函数被调用两次,以及为什么在一种情况下使用两个实例,而在另一种情况下只使用第二个实例。
最佳答案
其实我觉得这个问题与Initialize函数是定义在Class内部还是外部无关。这是因为全局变量data0和函数定义不在同一个文件中。
C++中的static结构还有一个含义,就是全局变量,即变量只在当前文件可见。
您在头文件中定义'static TestData data0 = TestData()',并将其包含在cpp 实现文件中。而且我猜你还将它包含在测试 cpp 文件中,这会导致头文件被包含两次。所以实际上有两个data0实例。
在调试代码时,您看到实现文件中的'data0'被设置为30,但实际上测试文件中的'data0'没有被修改。
尝试下面的代码,它应该可以正常工作。
.h
class TestData
{
public:
TestData(void);
~TestData(void);
int testValue;
static void Initialize();
};
extern TestData data0;
//.cpp
TestData data0 = TestData();
TestData::TestData(void){}
TestData::~TestData(void){}
void TestData::Initialize()
{
data0.testValue = 30;
}
上面的代码只在头文件中声明了TestData data0(extern表示变量在别处定义),在cpp文件中定义。所以在这种情况下,只有一个 data0 实例。
关于c++ - 当从静态方法而不是从类中的静态方法设置时,设置为实例的静态值有效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19979760/