我有很多C#代码,我必须用C ++编写。我在C ++方面没有太多经验。
我正在使用Visual Studio 2012进行构建。该项目是C ++中的静态库(不是在C ++ / CLI中)。
我正在创建一些UnitTests,在C#版本中,他们有一个 TestData 类,一些静态实例 TestData 和一个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被设置,但是当它到达时,Asset返回到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 ++(在类外声明的Initialize方法):
使用这样的代码我的测试工作。
//.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)时,调用顺序为:
当我的测试工作(在课堂外进行初始化)时,调用顺序是:
现在我理解为什么我的测试失败了。但我不明白为什么构造函数被调用两次,为什么在一种情况下使用两个实例,而在另一种情况下只使用第二个实例。
答案 0 :(得分:1)
实际上我认为这个问题与是否在Class内部或外部定义Initialize函数无关。这是因为全局变量data0和函数定义不在同一个文件中。
c ++中的静态构造具有全局变量的另一含义,这意味着该变量仅在当前文件中可见。
在头文件中定义'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实例。