1

考虑以下类:

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();

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

更新:添加了析构函数

4

2 回答 2

2

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

Stats statObject = Stats();

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

情况也是如此:

Stats statObject;
statObject = Stats();

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

您需要遵循三法则并为该类提供复制构造函数和复制赋值运算符。

于 2013-04-14T11:06:01.310 回答
1

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

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

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);
于 2013-04-14T11:14:43.067 回答