使用参数调用Constructor会重置先前初始化的数据元素-释放/调试VS17

时间:2018-11-15 17:31:52

标签: c++ visual-studio-2017

我目前几乎是第一次使用类(C ++),目的是要做一些有用的事情。那就是我遇到的第一个问题:D 我了解到,在定义对象后立即调用不带参数的构造函数。它实际上是做什么的。 但是由于某种原因,Visual Studio 2017进入发布/调试设置时会有一些奇怪的行为。当设置为“ Debug”时,调用带有参数的构造函数,在没有参数的情况下,先前定义的“ test”数据元素将返回未初始化状态。 在“发布”模式下,“测试”数据元素保持初始化为值44(如果析构函数为空,否则显示test = 0)。

这是某种预期的行为吗?

提前谢谢! :)

此示例应触发问题:

#include <iostream>

class Class
{
public:
    Class()
    {
        std::cout << "Constructor()\n";
        test = 44;
    }

    Class(int parameter)
    {
        std::cout << "Constructor(param): " << parameter;
    }

    ~Class() { std::cout << "Destructor"; }

    void get(void)
    {
        std::cout << "test = " << test << '\n';
    }

protected:
    int test;
};

int main()
{
    Class Ins;       // constructor without parameters gets called
    Ins.get();       // outputs 44
    Ins = Class(55); // constructor with parameters gets called

    Ins.get();       // *PROBLEM* should show 44 at all time?

    /*
    DEBUG-MODE -> test = (undefined rubbish)

                  _ empty destructor:            test = 44;
                 /
    RELEASE MODE-
                 \_ destructor with cout output:  test = 0;
    */
}

输出:

Constructor()
test = 44
Constructor(param): 55
Destructor
test = -858993460  /* <- for debug build */
test = 44 /* <- for release build (empty destructor) */
test = 0 /* <- for release build (cout inside destructor) */

Destructor

但是我希望在所有情况下都test = 44

1 个答案:

答案 0 :(得分:3)

具有参数的构造函数:

Class::Class(int parameter)
{
    cout << "Constructor(param)" << parameter;
}

实际上没有设置test。因此,test对象将在构造Class对象之后进行未初始化(技术上是默认初始化)并具有未指定的值。

Ins = Class(55);中,您将使用Class(55)创建一个这样的实例,然后将其分配给另一个实例Ins。缺少一些例外,编译器将自动生成一个赋值运算符,该运算符会将变量test从右侧实例复制到左侧实例。因此,在Ins = Class(55);之后,实例Instest中将具有未指定的值。

由于未指定变量的值,因此编译器可以选择在其中使用任何值,并且完全可以根据编译器选项(例如Debug / Release Mode)甚至在不同的程序调用中提供不同的值。

始终最好通过成员初始化列表设置构造函数中的所有成员,如下所示:

Class::Class(int parameter)
    : test(parameter)
{
    cout << "Constructor(param)" << parameter;
}

Class::Class()
    : test(0)
{
    std::cout << "Constructor()\n";
}