如何在另一个构造函数中正确调用默认构造函数

时间:2016-01-10 14:50:28

标签: c++ constructor

如果我在另一个构造函数中调用默认构造函数,它会崩溃我的程序。我相信array_不是在默认构造函数中动态分配的。我该如何解决这个问题。

template < typename T >
class Matrix
{
public :
    size_t n_{1};
    size_t m_{1};
    T* array_{nullptr};
 public  :
    Matrix();
    Matrix(size_t n, size_t m) {
        n_ = n;
        m_ = m;
        array_  = new T[n_ * m_];
        Matrix();
    }
}
template < typename T >
Matrix<T>::Matrix(){
for(int i=0;i < n_ * m_; i++)
    array_[i] = {};
}

4 个答案:

答案 0 :(得分:5)

我会像这样构建代码:

template <typename T>
class Matrix
{
    size_t n_;
    size_t m_;
    T* array_;

public:
    Matrix() : Matrix(1, 1) {}

    Matrix(size_t n, size_t m) : n_(n), m_(m), array_(new T[n_ * m_]()) {}

    ~Matrix() { delete [] array_; }

    // ...
};

这实现了与您的代码预期相同的效果(即默认构造函数生成1×1矩阵,并且所有元素都进行了值初始化),但它使用核心语言功能来简洁地表达:

  • 初始化程序列表初始化类成员,无需任何分配。
  • array-new表达式可以使用初始值设定项()对每个元素进行值初始化;不需要循环。
  • 默认构造函数委托给一般构造函数。

如果您计划使矩阵类可复制,请务必遵守五条规则。如果您只需要一个不可复制(但可移动)的类型,那么将array_的类型更改为std::unique_ptr<T[]>并删除自定义析构函数。

答案 1 :(得分:2)

而不是提供的无效代码,

template < typename T >
class Matrix
{
public :
    size_t n_{1};
    size_t m_{1};
    T* array_{nullptr};
 public  :
    Matrix();
    Matrix(size_t n, size_t m) {
        n_ = n;
        m_ = m;
        array_  = new T[n_ * m_];
        Matrix();
    }
}
template < typename T >
Matrix<T>::Matrix(){
for(int i=0;i < n_ * m_; i++)
    array_[i] = {};
}

只需使用std::vector存储:

template < typename T >
class Matrix
{
private:
    Size n_ = 1;
    Size m_ = 1;
    std::vector<T> array_;

public :
    Matrix(): array_(1) {}

    Matrix( const Size n, const Size m )
        : n_( n ), m_( m ), array_( n*m )
    {}
};

这将处理矩阵元素的默认初始化。

它还负责复制,这将导致原始代码的未定义行为。

在其他新闻中,你想要一个默认初始化的原始数组,或者更确切地说是一个“值初始化的”原始数组,你可以

new T[size]()

()请求初始化。

这比使用循环更简洁:它避免了代码,并且它避免了使用默认构造函数对类项类型执行两次。

但现在不要这样做:只需使用std::vector进行存储,如上所述。

答案 2 :(得分:1)

您并不需要默认构造函数,因为您需要默认的构造函数参数。

委托c&#39;添加到c ++ 11中意味着添加&#34;做一些基础工作然后一些&#34;的选项。在您的情况下,没有基础工作,只有默认大小参数。

您提供的代码不完整,但如果您不打算使用std :: vector,请不要忘记关注rule of three(现在有五个c ++ 11)

template < typename T >
class Matrix
{
private:
    int n_;
    int m_;
    T* array_{nullptr};
 public  :
    Matrix(int n = 1, int m = 1 ) : n_{n}, m_{m} {
        array_ = new T[m * n];
        for(int i=0;i < n_ * m_; i++)
          array_[i] = 0; // If you want specific values
                         // otherwise no need for the loop.
        }
    }
};

答案 3 :(得分:0)

正如您所做的那样,您不应该这样做,因为默认构造函数只会分配一个1的数组。

但是,您可以做的是从默认构造函数委托给接受两个值的构造函数。

 Matrix() : Matrix(1,1) {};
 Matrix(size_t m, size_t n) : array(new T [n*m]), n_(n), m_(m)
 {
      for(int i=0;i < n_ * m_; i++)
          array_[i] = {};
 };

函数体(包括构造函数)中的语句Matrix()构造一个单独的临时对象。它不是构造函数委托。

相关问题