4

我多年没有使用 C++,现在我用测试编写了 C++ 项目。

当我开始调试时,我发现变量默认不初始化为零很奇怪。例如,当我查看我的类未初始化变量(unsigned int)时,我看到它的值 3452816845 insted of expected zeo ...这会导致单元测试中的错误。我使用这样的初始化:

TEST_METHOD(TestPlus)
        {
            Entity* entity = new Entity();
            entity->mCreateOperator(entity->Plus);
            entity->SetContactValue(1);
            entity->SetContactValue(2);
            entity->mProcessLast();
            Assert::IsTrue(entity->GetContactValue((1+2));
        }

我有实体类的默认构造函数:

Entity::Entity(void)    {/*some internal array initialization*/}

我认为当我使用 new 关键字时,所有类变量都将由 C++ 运行时初始化为 0。

我错过了什么吗?

4

3 回答 3

5

您的类的数据成员未初始化,特别是因为您明确要求编译器未初始化它们。您通过编写一个默认构造函数来完成此操作,该构造函数不执行任何初始化它们的操作

Entity::Entity(void) { /*some internal array initialization*/ }

如果你的类没有用户定义的构造函数,那么这个语法

Entity* entity = new Entity();

将触发新对象的所谓值初始化,这确实会将所有直接标量数据成员设置Entity为零。

但是,在您编写自己的默认构造函数的那一刻,Entity::Entity()您基本上告诉编译器您想要禁止Entity类的值初始化并且您想要手动初始化这些成员。所以现在你必须做到这一点:手动初始化Entity. 由于您没有在构造函数中执行此操作,因此这些成员未初始化。

于 2013-09-07T16:26:39.547 回答
4

实际上,值3452816845(0xCDCDCDCD) 是 Microsoft 运行时用来识别未初始化变量的特殊填充模式。编译器这样做是为了让您可以检测何时忘记初始化变量,并且该值被选为“好”值,因为它不是有效地址并且是无符号的大数字,并且是“大”有符号范围内的负数,因此当您的代码使用这些值之一时,通常很容易注意到出现问题 - 它几乎总是超出您期望的范围。

于 2013-09-07T15:58:41.107 回答
3

除非该类型具有默认构造函数或者是静态变量,否则它根本不会被初始化。因此,读取该值是未定义的行为。

int a; //namespace scope (static storage) - value-initialized (0)
void foo()
{
    int x;  
    //reading x is illegal, you can only assign to it
    static int y;
    //guaranteed to be value-initialized (0)
}
于 2013-09-07T13:42:29.517 回答