从静态方法设置而不是从类中的静态方法设置时,静态值设置为实例?

时间:2013-11-14 14:05:23

标签: c++ visual-c++ testing static

我有很多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)时,调用顺序为:

  1. TestData(data0)构造函数(地址:1)
  2. TestData(data0)构造函数(地址:2)
  3. 初始化:将数据0与地址1
  4. 一起使用
  5. 测试:将数据0与地址2
  6. 一起使用

    当我的测试工作(在课堂外进行初始化)时,调用顺序是:

    1. TestData(data0)构造函数(地址:1)
    2. TestData(data0)构造函数(地址:2)
    3. 初始化:将数据0与地址2
    4. 一起使用
    5. 测试:将数据0与地址2
    6. 一起使用

      现在我理解为什么我的测试失败了。但我不明白为什么构造函数被调用两次,为什么在一种情况下使用两个实例,而在另一种情况下只使用第二个实例。

1 个答案:

答案 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实例。