我有很多用C ++编写的C#代码。我没有太多的C ++经验。

我正在使用Visual Studio 2012进行构建。该项目是C ++(而不是C ++ / CLI)中的静态库。

我正在C#版本中创建一些UnitTest,它们有一个TestData类,一些TestData的静态实例以及一个将这些静态实例的值设置为静态的Initialize方法。

当我在C ++中尝试相同时,我发现如果在TestData类中声明了Initialize方法,则该方法无效。但是,如果我在外面声明它,它会起作用。

C ++(测试)

TEST_CLASS(UnitTest1)
{
public:
    TEST_CLASS_INITIALIZE(ClassInitialize)
    {
        TestData::Initialize();
    }

    TEST_METHOD(TestMethod1)
    {
        Assert::AreEqual(data0.testValue, 30);
    }
};


C ++(TestData类中的Initialize方法):

测试失败,并声明了Initialize方法,如下所示。调试时,我看到已设置了testValue,但到达资产时,其值又回到了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;
    }
}


为什么会这样呢?

更新:

根据汉斯的建议,我跟踪了所使用变量的地址。它使我注意到,由于某种原因,TestData的构造函数被调用了两次。我不知道为什么我以为可能正在调用自动​​分配,所以我在构造函数中添加了一个int参数,以查看会发生什么,并且看来它两次调用了data0的构造函数。

当我的测试不起作用(在类中具有Initialize)时,调用顺序为:


TestData(data0)构造函数(地址:1)
TestData(data0)构造函数(地址:2)
初始化:将data0与地址1一起使用
测试:使用data0和地址2


当我的测试有效时(在班级外进行初始化),调用顺序为:


TestData(data0)构造函数(地址:1)
TestData(data0)构造函数(地址:2)
初始化:将data0与地址2一起使用
测试:使用data0和地址2


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

最佳答案

实际上,我认为问题与在类内部还是外部定义Initialize函数无关。这是因为全局变量data0和函数定义不在同一文件中。

c ++中的静态构造具有全局变量的另一种含义,这意味着该变量仅在当前文件中可见。

您在头文件中定义“静态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/

10-12 20:43