和我一起写矩阵类(二)
大连理工大学软件学院WAKU(转载请保留署名)类的方法(也可叫做成员函数)从构造函数开始,我写的一个构造函数是这样的:
template <class T>
CMatrix<T>::CMatrix(void)
{
m = 0; n = 0;
p = NULL;
}
由于使用了模板,所以在每个成员函数之前都要加上template <class T>,而且类名后一定要加上<T>,否则会编译出错。这是一个无参的构造函数,里面把行列值赋0,把数组的指针置为空,这是一个好习惯。除了安全带来的另一个好处是避免了定义对象数组时写出一长串的初始化表。
如果有可能定义类的对象数组,最好提供类的无参构造函数
然后再提供另外的成员函数完成有参构造函数所完成的功能。我写的一个有参构造函数是:
template <class T>
CMatrix<T>::CMatrix(int m, int n)
{
int i, j;
p = new T*[m];
for (i = 0; i < m; i++)
{
p[i] = new T[n];
for (j = 0; j < n; j++)
{
p[i][j] = 0;
}
}
this->m = m; this->n = n;
}
这是有参构造函数所完成的功能,无参构造函数由于不知道行列的具体值所以不能加入以上代码,所以我们必须要另写一个一模一样的函数“补充”这个功能:
template <class T>
void CMatrix<T>::SetMatrix(int m, int n)
{
int i, j;
p = new T*[m];
for (i = 0; i < m; i++)
{
p[i] = new T[n];
for (j = 0; j < n; j++)
{
p[i][j] = 0;
}
}
this->m = m; this->n = n;
}
这两段代码实现了动态创建m行n列二维数组的功能。p = new T*[m];语句和第一篇里创建一维数组的语句非常类似,这里申请了有m个T类型的指针数组(即数组里存放的全是指向T类型的指针),并把这个数组的首地址赋给了p。然后外层for循环遍历数组里的每一个指针,并用每个指针p[i]接收由new创建的n个T类型数组。
明白前面我讲过二维数组,这段代码也就很好理解,p[i]是一个行指针,p[0]相当于double array[3][3]里的array[0]、p[1]就相当于array[1];然后每个行指针又“管辖”着刚申请的n个元素。里层for循环把这一行的元素值初始为0。其实说穿了也很简单吧。
下面把析构函数完成,很简单,就是释放申请的空间:
template <class T>
CMatrix<T>::~CMatrix(void)
{
int i;
if (p)
{
for (i = 0; i < m; i++)
{
delete[] p[i];
}
delete[] p;
}
}
记住一点,有几个new就要有几个delete。另外注意一点,delete后面的[]一定不要落下,否则编译器并不会报错,你的内存却还照样泄漏。
矩阵里面有一个二维数组,那么一个可以把二维数组填充到到矩阵里的函数无疑是非常有用的。让我们实现它吧:
template <class T>
CMatrix<T>::CMatrix(int m, int n, T* array)
{
int i, j;
p = new T*[m];
for (i = 0; i < m; i++)
{
p[i] = new T[n];
for (j = 0; j < n; j++)
{
p[i][j] = array[i*n+j];
}
}
this->m = m; this->n = n;
}
这是一个构造函数,用于在创建对象时就用二维数组赋值,对应重载的SetMatrix函数如下:
template <class T>
void CMatrix<T>::SetMatrix(int m, int n, T* array)
{
int i, j;
if (p)
{
for (i = 0; i < this->m; i++)
{
delete[] p[i];
}
delete[] p;
}
p = new T*[m];
for (i = 0; i < m; i++)
{
p[i] = new T[n];
for (j = 0; j < n; j++)
{
p[i][j] = array[i*n+j];
}
}
this->m = m; this->n = n;
}
由于调用SetMatrix函数时的对象有可能已经申请了空间,所以再数组赋值之前应该释放掉。
我们不是要传递二维数组吗?为什么第三个参数是T* array?这不是一个一级指针吗?不觉得赋值的时候用p[i][j] = array[i*n+j];这种语句很奇怪吗?请听下回分解
类的方法(也可叫做成员函数)从构造函数开始,我写的一个构造函数是这样的:
template <class T>
CMatrix<T>::CMatrix(void)
{
m = 0; n = 0;
p = NULL;
}
由于使用了模板,所以在每个成员函数之前都要加上template <class T>,而且类名后一定要加上<T>,否则会编译出错。这是一个无参的构造函数,里面把行列值赋0,把数组的指针置为空,这是一个好习惯。除了安全带来的另一个好处是避免了定义对象数组时写出一长串的初始化表。
如果有可能定义类的对象数组,最好提供类的无参构造函数
然后再提供另外的成员函数完成有参构造函数所完成的功能。我写的一个有参构造函数是:
template <class T>
CMatrix<T>::CMatrix(int m, int n)
{
int i, j;
p = new T*[m];
for (i = 0; i < m; i++)
{
p[i] = new T[n];
for (j = 0; j < n; j++)
{
p[i][j] = 0;
}
}
this->m = m; this->n = n;
}
这是有参构造函数所完成的功能,无参构造函数由于不知道行列的具体值所以不能加入以上代码,所以我们必须要另写一个一模一样的函数“补充”这个功能:
template <class T>
void CMatrix<T>::SetMatrix(int m, int n)
{
int i, j;
p = new T*[m];
for (i = 0; i < m; i++)
{
p[i] = new T[n];
for (j = 0; j < n; j++)
{
p[i][j] = 0;
}
}
this->m = m; this->n = n;
}
这两段代码实现了动态创建m行n列二维数组的功能。p = new T*[m];语句和第一篇里创建一维数组的语句非常类似,这里申请了有m个T类型的指针数组(即数组里存放的全是指向T类型的指针),并把这个数组的首地址赋给了p。然后外层for循环遍历数组里的每一个指针,并用每个指针p[i]接收由new创建的n个T类型数组。
明白前面我讲过二维数组,这段代码也就很好理解,p[i]是一个行指针,p[0]相当于double array[3][3]里的array[0]、p[1]就相当于array[1];然后每个行指针又“管辖”着刚申请的n个元素。里层for循环把这一行的元素值初始为0。其实说穿了也很简单吧。
下面把析构函数完成,很简单,就是释放申请的空间:
template <class T>
CMatrix<T>::~CMatrix(void)
{
int i;
if (p)
{
for (i = 0; i < m; i++)
{
delete[] p[i];
}
delete[] p;
}
}
记住一点,有几个new就要有几个delete。另外注意一点,delete后面的[]一定不要落下,否则编译器并不会报错,你的内存却还照样泄漏。
矩阵里面有一个二维数组,那么一个可以把二维数组填充到到矩阵里的函数无疑是非常有用的。让我们实现它吧:
template <class T>
CMatrix<T>::CMatrix(int m, int n, T* array)
{
int i, j;
p = new T*[m];
for (i = 0; i < m; i++)
{
p[i] = new T[n];
for (j = 0; j < n; j++)
{
p[i][j] = array[i*n+j];
}
}
this->m = m; this->n = n;
}
这是一个构造函数,用于在创建对象时就用二维数组赋值,对应重载的SetMatrix函数如下:
template <class T>
void CMatrix<T>::SetMatrix(int m, int n, T* array)
{
int i, j;
if (p)
{
for (i = 0; i < this->m; i++)
{
delete[] p[i];
}
delete[] p;
}
p = new T*[m];
for (i = 0; i < m; i++)
{
p[i] = new T[n];
for (j = 0; j < n; j++)
{
p[i][j] = array[i*n+j];
}
}
this->m = m; this->n = n;
}
由于调用SetMatrix函数时的对象有可能已经申请了空间,所以再数组赋值之前应该释放掉。
我们不是要传递二维数组吗?为什么第三个参数是T* array?这不是一个一级指针吗?不觉得赋值的时候用p[i][j] = array[i*n+j];这种语句很奇怪吗?请听下回分解
类的方法(也可叫做成员函数)从构造函数开始,我写的一个构造函数是这样的:
template <class T>
CMatrix<T>::CMatrix(void)
{
m = 0; n = 0;
p = NULL;
}
由于使用了模板,所以在每个成员函数之前都要加上template <class T>,而且类名后一定要加上<T>,否则会编译出错。这是一个无参的构造函数,里面把行列值赋0,把数组的指针置为空,这是一个好习惯。除了安全带来的另一个好处是避免了定义对象数组时写出一长串的初始化表。
如果有可能定义类的对象数组,最好提供类的无参构造函数
然后再提供另外的成员函数完成有参构造函数所完成的功能。我写的一个有参构造函数是:
template <class T>
CMatrix<T>::CMatrix(int m, int n)
{
int i, j;
p = new T*[m];
for (i = 0; i < m; i++)
{
p[i] = new T[n];
for (j = 0; j < n; j++)
{
p[i][j] = 0;
}
}
this->m = m; this->n = n;
}
这是有参构造函数所完成的功能,无参构造函数由于不知道行列的具体值所以不能加入以上代码,所以我们必须要另写一个一模一样的函数“补充”这个功能:
template <class T>
void CMatrix<T>::SetMatrix(int m, int n)
{
int i, j;
p = new T*[m];
for (i = 0; i < m; i++)
{
p[i] = new T[n];
for (j = 0; j < n; j++)
{
p[i][j] = 0;
}
}
this->m = m; this->n = n;
}
这两段代码实现了动态创建m行n列二维数组的功能。p = new T*[m];语句和第一篇里创建一维数组的语句非常类似,这里申请了有m个T类型的指针数组(即数组里存放的全是指向T类型的指针),并把这个数组的首地址赋给了p。然后外层for循环遍历数组里的每一个指针,并用每个指针p[i]接收由new创建的n个T类型数组。
明白前面我讲过二维数组,这段代码也就很好理解,p[i]是一个行指针,p[0]相当于double array[3][3]里的array[0]、p[1]就相当于array[1];然后每个行指针又“管辖”着刚申请的n个元素。里层for循环把这一行的元素值初始为0。其实说穿了也很简单吧。
下面把析构函数完成,很简单,就是释放申请的空间:
template <class T>
CMatrix<T>::~CMatrix(void)
{
int i;
if (p)
{
for (i = 0; i < m; i++)
{
delete[] p[i];
}
delete[] p;
}
}
记住一点,有几个new就要有几个delete。另外注意一点,delete后面的[]一定不要落下,否则编译器并不会报错,你的内存却还照样泄漏。
矩阵里面有一个二维数组,那么一个可以把二维数组填充到到矩阵里的函数无疑是非常有用的。让我们实现它吧:
template <class T>
CMatrix<T>::CMatrix(int m, int n, T* array)
{
int i, j;
p = new T*[m];
for (i = 0; i < m; i++)
{
p[i] = new T[n];
for (j = 0; j < n; j++)
{
p[i][j] = array[i*n+j];
}
}
this->m = m; this->n = n;
}
这是一个构造函数,用于在创建对象时就用二维数组赋值,对应重载的SetMatrix函数如下:
template <class T>
void CMatrix<T>::SetMatrix(int m, int n, T* array)
{
int i, j;
if (p)
{
for (i = 0; i < this->m; i++)
{
delete[] p[i];
}
delete[] p;
}
p = new T*[m];
for (i = 0; i < m; i++)
{
p[i] = new T[n];
for (j = 0; j < n; j++)
{
p[i][j] = array[i*n+j];
}
}
this->m = m; this->n = n;
}
由于调用SetMatrix函数时的对象有可能已经申请了空间,所以再数组赋值之前应该释放掉。
我们不是要传递二维数组吗?为什么第三个参数是T* array?这不是一个一级指针吗?不觉得赋值的时候用p[i][j] = array[i*n+j];这种语句很奇怪吗?请听下回分解