c++ - 当从静态方法而不是从类中的静态方法设置时,设置为实例的静态值有效吗?

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

我有很多 C# 代码必须用 C++ 编写。我在 C++ 方面没有太多经验。

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

我正在创建一些单元测试,在 C# 版本中,它们有一个类 TestData、一些 TestDatastatic 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),调用顺序是:

  1. TestData (data0) 构造函数(地址:1)
  2. TestData (data0) 构造函数(地址:2)
  3. 初始化:使用 data0 和 Address 1
  4. 测试:使用 data0 和 Address 2

当我的测试工作时(在类外初始化)调用顺序是:

  1. TestData (data0) 构造函数(地址:1)
  2. TestData (data0) 构造函数(地址:2)
  3. 初始化:使用 data0 和 Address 2
  4. 测试:使用 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/

相关文章:

C++ 矩阵乘法不产生正确的输出

c++ - 为什么要在结构内部初始化 const 静态变量?

c++ - bool返回值的函数,只设置整个寄存器的1个字节

visual-studio-2010 - 如何在 Visual C++ 2010 中添加要链接的 lib 文件?

c# - 什么是vc++中的HWND

ruby-on-rails - 如何在 Rails 3 中进行集成测试?

c++ - std::source_location 作为非类型模板参数

C++代码编译但在运行时失败

haskell - 为复杂类型创建任意实例

python - 模拟 - 引发异常的补丁类方法