【C++】实现两维动态类模板遇到的问题。。。

充实的虚 2014-12-14 03:32:48
各位高手,小菜正在学习C++,最近老师布置了一个小课题让我们做。

我参考《C++语言程序设计(第四版)》郑莉 董渊 何江舟 编著 清华大学出版社 一书,尝试结合书中关于一位动态数组类模板的内容,写一个二维的动态矩阵类模板,但是写好后运行测试,发现一维的动态类模板可以正确使用,但是二维的就不对了,特别是对二维矩阵的赋值运算符的重载(operator=),以及二维矩阵的尺寸变化函数(resize)的调用,总是出现问题。

我用的编程软件是Microsoft Visual Studio 2010。

以下是源代码

Mainhead.h:Main.cpp要用到的头文件

#ifndef MAIN
#define MAIN

#include <iostream>
#include <math.h>
#include <cassert>
#include <iomanip>
using namespace std;

#endif


Array.h:用于实现一维的动态类模板。这个头文件基本是从参考书中摘录下来的,应该没什么问题。


#ifndef ARRAY_H
#define ARRAY_H

#include "Mainhead.h"

const int PRECISION=6;

template <class T>
class Array
{
protected:
T* list;
int size;
public:
Array(const int& sz=50);
Array (const Array<T> &a);
~Array();
Array<T>& operator= (const Array<T> &rhs);
T & operator [](const int& i);
const T & operator[] (const int& i) const;
operator T* ();
operator const T*() const;
int getSize() const;
void resize(const int& sz);
template <typename T>
friend istream & operator>>(istream & in, Array<T>& a);
template <typename T>
friend ostream & operator<<(ostream & out, const Array<T> & a);
};
template <class T>
Array<T>::Array(const int& sz)
{
assert(sz>=0);
size=sz;
list=new T[size];
}
template <class T>
Array<T>::~Array()
{
delete [] list;
}

template <class T>
Array<T>::Array(const Array<T> &a)
{
size=a.size;
list=new T[size];
for (int i=0;i<size;i++)
{
list[i]=a.list[i];
}
}

template <class T>
Array<T>& Array<T>::operator= (const Array<T> &rhs)
{
if (&rhs!=this)
{
if (size!=rhs.size){
delete [] list;
size=rhs.size;
list=new T[size];}
for (int i=0;i<size;i++){
list[i]=rhs.list[i];}
}
return *this;
}

template <class T>
T & Array<T>::operator[] (const int& i)
{
assert(i>=0&&i<size);
return list[i];
}
template <class T>
const T& Array<T>::operator[](const int& i) const
{
assert(i>=0&&i<size);
return list[i];
}
template <class T>
Array<T>::operator T*() {return list;}

template <class T>
Array<T>::operator const T*() const {return list;}

template <class T>
int Array<T>::getSize() const {return size; }
template <class T>
void Array<T>::resize(const int& sz)
{
assert(sz>=0);
if (sz==size)
return;
T* newlist=new T[sz];
int n=(sz<size)?sz:size;
for (int i=0;i<n;i++){
newlist[i]=list[i];}
delete[] list;
list=newlist;
size=sz;
}

template <typename T>
istream & operator>>(istream & in, Array<T>& a )
{
for (int i=0;i<a.size;i++)
{ in >>a.list[i]; }
return in;
}

template <typename T>
ostream & operator<<(ostream & out, const Array<T> & a)
{
for (int i=0;i<a.size;i++)
{ out <<setprecision(PRECISION)<<a.list[i]<<' '; }
return out;
}
#endif



Matrix.h:用于实现二维的动态类模板。其中的赋值操作符重载、resize函数有问题,用起来不对

#ifndef MATRIX_H
#define MATRIX_H

#include "Mainhead.h"
#include "Array.h"

template <class T>
class Matrix
{
protected:
Array<T>* ary;
int rownum;
int colnum;
public:
Matrix(const int& rn=20,const int& cn=20);
Matrix(const Matrix<T> &mt);
~Matrix();
Matrix<T>& operator= (const Matrix<T> & mt);
Array<T> & operator [] (const int& i);
const Array<T> & operator [] (const int& i) const;
operator Array<T>* ();
operator const Array<T>*() const;
int getRownum() const;
int getColnum() const;
int getSize() const;
void resize(const int& rn,const int& cn);
template <typename T>
friend istream & operator>>(istream & in,Matrix<T> & mt);
template <typename T>
friend ostream & operator<<(ostream & out,const Matrix<T> & mt);
};
template <class T>
Matrix<T>::Matrix(const int& rn,const int& cn)
{
assert(rn>=0&&cn>=0);
rownum=rn;
colnum=cn;
ary=new Array<T>[rownum];
for (int i=0;i<rownum;i++)
{
ary[i]=*(new Array<T>);
ary[i].resize(colnum);
}
}
template <class T>
Matrix<T>::~Matrix()
{
rownum=0;
colnum=0;
for (int i=0;i<rownum;i++){
ary[i].~Array();
}
delete[] ary;
}

template <class T>
Matrix<T>::Matrix(const Matrix<T> & mt)
{
rownum=mt.rownum;
colnum=mt.colnum;
ary=new Array<T>[rownum];
for (int i=0;i<rownum;i++)
{
ary[i]=mt.ary[i];
}
}

template <class T>
Matrix<T>& Matrix<T>::operator=(const Matrix<T> &rhs)//赋值操作符重载,应该有问题,但没看出来
{
if (&rhs!=this)
{
if (rownum!=rhs.rownum||colnum!=rhs.colnum)
{

for (int i=0;i<rownum;i++)
{
ary[i].~Array();
}
delete[] ary;
ary=new Array<T>[rhs.rownum];
for (int i=0;i<rhs.rownum;i++)
{
ary[i]=rhs.ary[i];
}
rownum=rhs.rownum;
colnum=rhs.colnum;
}
}
return *this;
}
template <class T>
Array<T> & Matrix<T>::operator [] (const int& i)
{
assert(i>=0&&i<rownum);
return ary[i];
}
template <class T>
const Array<T> & Matrix<T>::operator[](const int& i) const
{
assert(i>=0&&i<rownum);
return ary[i];
}

template <class T>
Matrix<T>::operator Array<T>*() {return ary;}
template <class T>
Matrix<T>::operator const Array<T>*() const {return ary;}
template <class T>
int Matrix<T>::getRownum() const {return rownum;}
template <class T>
int Matrix<T>::getColnum() const {return colnum;}
template <class T>
int Matrix<T>::getSize() const {return rownum*colnum;}

template <class T>
void Matrix<T>::resize(const int& rn,const int& cn)//修改矩阵大小,貌似也有错误
{
assert(rn>=0&&cn>=0);
if (rn==rownum&&cn==colnum)
{return;}
Array<T>* newary=new Array<T>[rn];
int r=(rn<rownum)?rn:rownum;
for (int i=0;i<r;i++)
{
newary[i]=ary[i];
}
for (int i=0;i<rn;i++)
{
newary[i].resize(cn);
}
for (int i=0;i<rownum;i++)
{
ary[i].~Array();
}
delete[] ary;
for (int i=0;i<rn;i++)
{
ary[i]=newary[i];
}
ary=newary;
rownum=rn;
colnum=cn;
}

template <typename T>
istream & operator>>(istream & in,Matrix<T>& mt)
{
for (int i=0;i<mt.rownum;i++)
{ in >>mt.ary[i]; }
return in;
}

template <typename T>
ostream & operator<<(ostream & out,const Matrix<T>& mt)
{
for (int i=0;i<mt.rownum;i++)
{ out <<mt.ary[i]<<endl;}
return out;
}


#endif





#include "Mainhead.h"
#include "Array.h"
#include "Matrix.h"

void main()
{
double goon;
do
{
int row1,col1,row2,col2;//依次输入第一个矩阵的行数、列数,第二个矩阵的行数、列数
cin >>row1>>col1>>row2>>col2;
Matrix<double> mt1(row1,col1),mt2(row2,col2);
cin >>mt1;//输入第一个矩阵
mt2=mt1;//令第二个矩阵等于第一个矩阵
cout<<mt2;//输出第二个矩阵
cout<<"是否再来?(输入非零继续,输入零退出)";
cin >>goon;
}while(goon);
system("pause");
}


以上程序编译通过,但是运行时貌似运行到mt2=mt1时就卡住了,不知道该怎么办。求各位高人指点~
...全文
106 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
充实的虚 2014-12-15
  • 打赏
  • 举报
回复
谢谢高手点拨,我再理解下~~
引用 3 楼 zhao4zhong1 的回复:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
int **newarr2d(int rows,int cols) {
    int **p,i;

    p=(int **)malloc(rows*sizeof(int *));
    if (NULL==p) exit(1);
    for (i=0;i<rows;i++) {
        p[i]=(int *)malloc(cols*sizeof(int));
        if (NULL==p[i]) exit(1);
    }
    return p;
}
void deletearr2d(int **p,int rows) {
    int i;

    for (i=0;i<rows;i++) {
        free(p[i]);
    }
    free(p);
}
int main() {
    int **arr2d,i,j,r,c;

    r=4;
    c=5;
    //在堆中开辟一个4×5的二维int数组
    arr2d=newarr2d(r,c);
    for (i=0;i<r;i++) {
        for (j=0;j<c;j++) {
            arr2d[i][j]=i*c+j;
        }
    }
    for (i=0;i<r;i++) {
        for (j=0;j<c;j++) {
            printf(" %2d",arr2d[i][j]);
        }
        printf("\n");
    }
    deletearr2d(arr2d,r);

    r=6;
    c=3;
    //在堆中开辟一个6×3的二维int数组
    arr2d=newarr2d(r,c);
    for (i=0;i<r;i++) {
        for (j=0;j<c;j++) {
            arr2d[i][j]=i*c+j;
        }
    }
    for (i=0;i<r;i++) {
        for (j=0;j<c;j++) {
            printf(" %2d",arr2d[i][j]);
        }
        printf("\n");
    }
    deletearr2d(arr2d,r);

    return 0;
}
//  0  1  2  3  4
//  5  6  7  8  9
// 10 11 12 13 14
// 15 16 17 18 19
//  0  1  2
//  3  4  5
//  6  7  8
//  9 10 11
// 12 13 14
// 15 16 17
//
充实的虚 2014-12-15
  • 打赏
  • 举报
回复
谢谢高手解答,经过你的提醒,我总算解决了程序的问题。原来是我析构的理解错了,谢谢~~
引用 1 楼 fly_dragon_fly 的回复:
matrix 中 ary[i].~Array();这句不需要,你都有delete操作了,重复调用析构函数。 看前面ctor也有问题,里面的array是new出来的,后面也没有delete掉,这个对象就是动态数组了,不需要new的
赵4老师 2014-12-15
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
int **newarr2d(int rows,int cols) {
    int **p,i;

    p=(int **)malloc(rows*sizeof(int *));
    if (NULL==p) exit(1);
    for (i=0;i<rows;i++) {
        p[i]=(int *)malloc(cols*sizeof(int));
        if (NULL==p[i]) exit(1);
    }
    return p;
}
void deletearr2d(int **p,int rows) {
    int i;

    for (i=0;i<rows;i++) {
        free(p[i]);
    }
    free(p);
}
int main() {
    int **arr2d,i,j,r,c;

    r=4;
    c=5;
    //在堆中开辟一个4×5的二维int数组
    arr2d=newarr2d(r,c);
    for (i=0;i<r;i++) {
        for (j=0;j<c;j++) {
            arr2d[i][j]=i*c+j;
        }
    }
    for (i=0;i<r;i++) {
        for (j=0;j<c;j++) {
            printf(" %2d",arr2d[i][j]);
        }
        printf("\n");
    }
    deletearr2d(arr2d,r);

    r=6;
    c=3;
    //在堆中开辟一个6×3的二维int数组
    arr2d=newarr2d(r,c);
    for (i=0;i<r;i++) {
        for (j=0;j<c;j++) {
            arr2d[i][j]=i*c+j;
        }
    }
    for (i=0;i<r;i++) {
        for (j=0;j<c;j++) {
            printf(" %2d",arr2d[i][j]);
        }
        printf("\n");
    }
    deletearr2d(arr2d,r);

    return 0;
}
//  0  1  2  3  4
//  5  6  7  8  9
// 10 11 12 13 14
// 15 16 17 18 19
//  0  1  2
//  3  4  5
//  6  7  8
//  9 10 11
// 12 13 14
// 15 16 17
//
赵4老师 2014-12-15
  • 打赏
  • 举报
回复
模板和运算符重载都是语法糖。 语法糖越甜,编译调试查错越苦! 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中,我认为不值当。
fly_dragon_fly 2014-12-14
  • 打赏
  • 举报
回复
matrix 中 ary[i].~Array();这句不需要,你都有delete操作了,重复调用析构函数。 看前面ctor也有问题,里面的array是new出来的,后面也没有delete掉,这个对象就是动态数组了,不需要new的

65,207

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧