在主体中调用方法与在构造函数列表中调用方法之间的区别

Difference between calling a method within the body and calling it in a constructor-list

我有一个名为 Array2D 的 class 和一个复制构造函数 Array2D(const Array2D&)。我遇到的问题是,只要调用复制构造函数,我的程序就会停止。构造函数是:

Array2D(const Array2D& arr) {
    Array2D(arr.rows, arr.cols); //Sets the variables cols and rows and
                                 //sets a pointer T* ptr = new T[rows*cols]
    for(size_t i = 0; i < rows*cols; i++)
        ptr[i] = arr.ptr[i];
}

我将对另一个构造函数的调用移到了构造函数列表中:

Array2D(const Array2D& arr)
: Array2D(arr.rows, arr.cols) {
    for(size_t i = 0; i < rows*cols; i++)
        ptr[i] = arr.ptr[i];
}

谁能告诉我为什么第二个版本的代码有效而第二个版本无效?

P.S.: 这是从复制构造函数调用的构造函数。

Array2D(size_t r, size_t c)
: rows(r), cols(c), ptr(new T[r*c]) {}

Array2D(const Array2D& arr) {
    Array2D(arr.rows, arr.cols); //Sets the variables cols and rows and
                                 //sets a pointer T* ptr = new T[rows*cols]
    for(size_t i = 0; i < rows*cols; i++)
        ptr[i] = arr.ptr[i];
}

Array2D(arr.rows, arr.cols); 基本上是一个非操作。它创建一个临时 Array2d 然后它被销毁。这意味着 ptr 永远不会被初始化并且使用它是 undefined behavior.

Array2D(const Array2D& arr)
: Array2D(arr.rows, arr.cols) {
    for(size_t i = 0; i < rows*cols; i++)
        ptr[i] = arr.ptr[i];
}

您使用委托构造函数初始化成员变量,然后设置数组元素。