C++——实验1 CMatrix类设计与实现

一、实验要求:
1、构造函数
CMatrix(): 不带参数的构造函数;
CMatrix(int nRow, int nCol, double *pData=NULL) : 带行、列及数据指针等参数的构造函数,并且参数带默认值;
CMatrix(const char * strPath): 带文件路径参数的构造函数;
CMatrix(const CMatrix& m): 拷贝构造函数
此外会用列表初始化成员变量:CMatrix(): m_nRow(0), m_nCol(0), m_pData(NULL);
bool Create(int nRow, int nCol, double *pData=NULL): 先删除原有空间,根据传入行列创建空间,如果pData不为空要将pData的内容拷贝到m_pData中。

2、析构函数
~CMatrix(): 调用Release();
Release(): 将内存释放,并将行列设置为0;

3、运算符重载
算术运算符重载:+, -, +=, -=
关系运算符重载:>, <, ==
下标操作符:[], ()
强制类型转换: double
赋值运算符:=,尤其注意当m1=m1特殊情况的处理

4、友元函数
输入和输出运输符:<<, >>
二、实验过程
1.CMatrix.h

1: #ifndef CMATRIX_H
2: #define CMATRIX_H
3: #include <iostream>
4: using namespace std;
5: class CMatrix
6: {
7: public:
8:     CMatrix();
9:     CMatrix(int nRow,int nCol,double *pData=NULL);
10:     CMatrix(const CMatrix& m);
11:     CMatrix(const char * strPath);
12:     ~CMatrix();
13:     bool Create(int nRow,int nCol,double *pData=NULL);
14:     void Set(int nRow,int nCol,double dVale);
15:     void Release();
16:     friend istream & operator>>(istream& is,CMatrix & m);
17:     friend ostream & operator<<(ostream& os,const CMatrix &m);  
18:     
19:     CMatrix& operator=(const CMatrix& m);
20:     CMatrix& operator+=(const CMatrix& m);
21: //  CMatrix& operator+(const CMatrix& m);
22: //  CMatrix operator+(const CMatrix& m1,const CMatrix& m2);
23:     double & operator[](int nIndex);
24:     double & operator()(int nRow,int nCol);
25:     bool operator ==(const CMatrix& m);
26:     bool operator !=(const CMatrix& m);
27:     
28:     operator double();
29:     
30: private:
31:     int m_nRow;
32:     int m_nCol;
33:     double *m_pData;        
34: };
35: CMatrix operator+(const CMatrix& m1,const CMatrix& m2);
36:
37: inline void CMatrix::Set(int nRow,int nCol,double dVal)
38: {
39:     m_pData[nRow*m_nCol+nCol]=dVal;
40: }
41: #endif

2.CMatrix.cpp

1: #include "CMatrix.h"
2: #include <fstream>
3: #include <assert.h>
4: CMatrix::CMatrix():m_nRow(0),m_nCol(0),m_pData(0)
5: {
6:     
7: }
8: CMatrix::CMatrix(int nRow,int nCol,double *pData):m_pData(0)
9: {
10:     Create(nRow,nCol,pData);
11: }
12: CMatrix::CMatrix(const CMatrix& m):m_pData(0)
13: {
14:     *this = m;
15: }
16: CMatrix::CMatrix(const char * strPath)
17: {
18:     m_pData = 0;
19:     m_nRow = m_nCol = 0;
20:     ifstream cin(strPath);
21:     cin>>*this;
22: }
23: CMatrix::~CMatrix()
24: {
25:     Release();
26: }
27: bool CMatrix::Create(int nRow,int nCol,double *pData)
28: {
29:     Release();
30:     m_pData = new double[nRow*nCol];
31:     m_nRow = nRow;
32:     m_nCol = nCol;
33:     if(pData)
34:     {
35:         memcpy(m_pData,pData,nRow*nCol*sizeof(double));
36:     }
37: }
38: void CMatrix::Release()
39: {
40:     if(m_pData)
41:     {
42:         delete []m_pData;
43:         m_pData = NULL;
44:     }
45:     m_nRow = m_nCol = 0;
46: }
47: CMatrix& CMatrix::operator=(const CMatrix& m)
48: {
49:     if(this!=&m){
50:         Create(m.m_nRow,m.m_nCol,m.m_pData);
51:     }
52:     return *this;
53: }
54: CMatrix& CMatrix::operator+=(const CMatrix& m)
55: {
56:     assert(m_nRow==m.m_nRow && m_nCol==m.m_nCol);
57:     for(int i=0;i<m_nRow*m_nCol;i++)
58:     {
59:         m_pData[i]+=m.m_pData[i];
60:     }
61:     return *this;
62: }
63: //CMatrix& CMatrix::operator+(const CMatrix& m)
64: //{
65: //  assert(m_nRow==m.m_nRow && m_nCol==m.m_nCol);
66: //  for(int i=0;i<m_nRow*m_nCol;i++)
67: //  {
68: //      m_pData[i]+=m.m_pData[i];
69: //  }
70: //  return *this;
71: //}
72: //CMatrix CMatrix::operator+(const CMatrix& m1,const CMatrix& m2)
73: //{
74: //  CMatrix m3(m1);
75: //  m3+=m2;
76: //  return m3;
77: //}
78: CMatrix operator+(const CMatrix& m1,const CMatrix& m2)
79: {
80:     CMatrix m3(m1);
81:     m3 += m2;
82:     return m3;
83: }
84: double & CMatrix::operator[](int nIndex)
85: {
86:     assert(nIndex<m_nRow*m_nCol);
87:     return m_pData[nIndex];
88: }
89: double & CMatrix::operator()(int nRow,int nCol)
90: {
91:     assert(nRow*m_nCol+nCol<m_nRow*m_nCol);
92:     return m_pData[nRow*m_nCol+nCol];   
93: }
94: bool CMatrix::operator == (const CMatrix& m)
95: {
96:     if(!(m_nRow==m.m_nRow && m_nCol==m.m_nCol))
97:     {
98:         return false;
99:     }
100:     for(int i=0;i<m_nRow*m_nCol;i++)
101:     {
102:         if(m_pData[i]!=m.m_pData[i])
103:         {
104:             return false;
105:         }
106:     }
107:     return true;
108: }
109: bool CMatrix::operator !=(const CMatrix& m)
110: {
111:     return !((*this)==m);
112: }
113: CMatrix::operator double()
114: {
115:     double dS=0;
116:     for(int i=0;i<m_nRow*m_nCol;i++)
117:     {
118:         dS+=m_pData[i];
119:     }
120:     return dS;
121: }
122:     
123: istream & operator>>(istream& is,CMatrix & m)
124: {
125:     is>>m.m_nRow>>m.m_nCol;
126:     m.Create(m.m_nRow,m.m_nCol);
127:     for(int i=0;i<m.m_nRow*m.m_nCol;i++)
128:     {
129:         is>>m.m_pData[i];
130:     }
131:     return is;
132: }
133: ostream & operator<<(ostream& os,const CMatrix &m)
134: {
135:     os<<m.m_nRow<<" "<<m.m_nCol<<endl;
136:     double * pData = m.m_pData;
137:     for(int i=0;i<m.m_nRow;i++)
138:     {
139:         for(int j=0;j<m.m_nCol;j++)
140:         {
141:             os<<*pData++<<" ";
142:         }
143:         os<<endl;
144:     }
145:     return os;
146: }

3.main

1: #include <iostream>
2: /* run this program using the console pauser or add your own getch, system("pause")*/
3: #include "CComplex.h"
4: #include <stdio.h>
5: #include "CMatrix.h"
6: using namespace std;
7: int main(int argc, char** argv) {
8:     
9:     double pData[10]={2,3,4,5};
10:     CMatrix m1,m2(2,5,pData), m3("d:\\1.txt"),m4(m2);
11:     cin>>m1;
12:     m2.Set(1,3,10);
13:     cout<<m1<<m2<<m3<<m4;
14:     m4=m3;
15:     m4[2]=m4+1;
16:     if(m4==m3)
17:     {
18:         cout<<"Error !"<<endl;
19:     }
20:     m4 += m3;
21:     cout<<"sum of m4 = "<<(double)m4<<endl;
22:     return 0;
23: }

三、运行结果
在这里插入图片描述
四、实验总结
4.1构造函数与析构函数
构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。
析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作。
4.2运算符重载
运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。重载之后运算符的优先级和结合性不变;运算符重载的实质是函数重载。不能重载的运算符有:
(1)类属关系运算符“.”;(2)成员指针运算符“.*”;(3)作用域分辨符“::”;
(4)三目运算符“?:”
4.3友元函数
我们平时可以用流 std::cout<<str<<n ; std::cin>>str>>n ; 输出、输入字符串和整型等内置类型的值。但是对于我们自定义的类,比如 Student 类,却不能直接通过 cout<<Student 或 cin>>Student 这样的形式来输出类的内容或给类赋值。怎么办呢?我们可以通过重载输出、输入运算符,让自定义的类也支持这样的操作。

1.在引入iostream头文件,标准的命名空间的后,ostream 输出流(类),其中cout是它的一个对象, istream输入流对象,cin是它的一个对象。
2.输入输出流对象一般只是对内置类型进行输出,对对象的输出要进行运算符的重载
3.输入、输出运算符的重载,一般通过友元函数,进行实现,友元函数可以访问一个类的私有数据,通过友元函数可以实现对类的输出;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值