我的Stats类打印垃圾

时间:2013-04-14 10:58:54

标签: c++ pointers

考虑以下课程:

class Stats
{
    private:
    int arraySize; // size of array

    int * data; // pointer to data, an array of integers

    // default size of array in default constructor
    static const int DEFAULT_SIZE = 10;

    public:
    Stats() // default constructor
    {
        arraySize = DEFAULT_SIZE; // element count set to 10

        data = new int[DEFAULT_SIZE]; // array of integers
        srand((unsigned int) time(NULL)); // seeds rand() function

        // initializes integer array data with random values
        for (int i = 0; i < DEFAULT_SIZE; i++)
        {
            // data filled with value between 0 and 10
            data[i] = rand() % (DEFAULT_SIZE + 1);
        }
    }

    ~Stats() // destructor that deletes data memory allocation
    {
        delete [] data;
    }

    void displaySampleSet(int numbersPerLine)
    {
        cout << "Array contents:" << endl; // user legibility

        // iterates through array and prints values in array data
        for (int i = 0; i < arraySize; i++)
        {
            cout << data[i];

            /*  nested if statements that either prints a comma between
            values or skips to next line depending on value of numbersPerLine   */
            if (i + 1 < arraySize)
            {
                if ((i + 1) % numbersPerLine != 0)
                    cout << ", ";
                else
                    cout << endl;
            }
        }
    }
}

出于某种原因,当我以下列方式创建Stats对象时:

Stats statObject = Stats();

然后在其上调用displaySampleSet(),数字显示正常。但是,在以下列方式创建Stats对象时,该函数会打印垃圾:

Stats statObject;
statObject = Stats();

我不知道为什么会这样做并且感觉它与整数指针'data'和/或对象的创建方式有关但是我不确定是什么......所有和所有帮助完全赞赏!非常感谢你。

更新:已添加析构函数

2 个答案:

答案 0 :(得分:2)

两个代码语句都会产生未定义的行为。幸运的是,第一个有效,而第二个无效。

Stats statObject = Stats();

是复制初始化。它通过调用默认构造函数来复制创建的Stats对象,然后通过调用复制构造函数将其复制到statObject。请注意,您的类不提供复制构造函数,因此使用隐式生成的类。这将创建动态分配成员的浅表副本。创建此副本的对象最终会被销毁,然后在您的类中留下的是悬挂指针,这些指针不指向任何有效的内容。复制构造函数需要执行深层复制。

同样的情况:

Stats statObject;
statObject = Stats();

其中调用编译器生成的复制赋值运算符。导致与案例1中类似的问题。

您需要按照 Rule of Three 提供该类的复制构造函数和复制赋值运算符。

答案 1 :(得分:1)

您的代码使用的是合成复制构造函数,编译器定义的赋值运算符。 此外,您不会释放为默认构造函数动态分配的内存。 你必须定义你自己的复制construcor,重载赋值运算符(遵循三条规则)。

两种情况都是未定义的行为

Stats statObject;
statObject = Stats();  //using compiler defined assignment operator.

Stats statObject = Stats();  //using compiler defined copy constructor.

这里生成的临时对象是使用由编译器重载的赋值运算符,并且正在执行浅拷贝而不是深拷贝。 重载赋值运算符:

Stats& operator=(const Stats& rhs);

定义复制构造函数:

Stats(const Stats& rhs);