实验1 CMatrix类设计与实现
一、头文件的创建
C++对于创建一个类以及各项方法的推荐做法是在头文件.h中将类中所有的函数,变量预先定义,之后再在另一个.cpp文件中将这些所有方法一一实现,所以我们需要将我们对于矩阵类(我们之后都用CMatrix来表示这个类)的所有变量都在CMatrix.h中全部定义出来
#ifndef CMATRIX_H
#define CMATRIX_H
#include <iostream>
#include <string.h>
using namespace std;
class CMatrix
{
public:CMatrix();CMatrix(int nRow,int nCol,double *pData=NULL);CMatrix(const char * strPath);CMatrix(const CMatrix & m);~CMatrix();bool Create(int nRow,int nCol,double *pData=NULL);void Set(int nRow,int nCol,double dVale);void Release();friend istream & operator>>(istream& is,CMatrix & m);friend ostream & operator<<(ostream& os,const CMatrix &m);CMatrix& operator=(const CMatrix& m);CMatrix& operator+=(const CMatrix& m);double & operator[](int nIndex);double & operator()(int nRow,int nCol){return m_pData[nRow*m_nCol+nCol];}bool operator ==(const CMatrix& m);bool operator !=(const CMatrix& m);operator double();private:int m_nRow;int m_nCol;double * m_pData;
};
CMatrix operator+(const CMatrix& m1,const CMatrix& m2);inline void CMatrix::Set(int nRow,int nCol,double dVal)
{m_pData[nRow*m_nCol+nCol]=dVal;
}
#endif
。
二、各类构造器的创建
接下来我们都是在CMatrix.cpp文件下实现这些方法,先引用一下头文件
#include "cmatrix.h"
#include <fstream>
#include <assert.h>
#include <string.h>
1.不带参数的构造器
CMatrix::CMatrix():m_nRow(0),m_nCol(0),m_pData(NULL)
{}
2.带行、列及数据指针等参数的构造函数,并且参数带默认值;
CMatrix::CMatrix(int nRow,int nCol,double * pData):m_pData(NULL)
{Create(nRow,nCol,pData);
}
bool CMatrix::Create(int nRow,int nCol,double *pData)
{Release();m_pData = new double[nRow*nCol];m_nRow = nRow;m_nCol = nCol;if(pData){memcpy(m_pData,pData,nRow*nCol*sizeof(double));}return true;
}
void CMatrix::Release()
{if(m_pData){delete []m_pData;m_pData = NULL;}m_nRow = m_nCol = 0;
}
3.带文件路径参数的构造函数;
在许多大规模对类的操作中,我们需要使用文件输入用来代替繁杂的手动输入数值,所以创造从文件输入来创造类变量对于类的完整性也是非常重要的:
CMatrix::CMatrix(const char * strPath)
{m_pData = NULL;m_nRow = m_nCol = 0;ifstream cin(strPath);cin>>*this;
}
但是这里注意普通的 ‘>>’ 运算符只能传入一些整形数,浮点数,字符串,他是不知道如何读取我们创建的这个类,所以我们还需要对该运算符进行重载:
friend istream & operator>>(istream& is,CMatrix & m);istream & operator>>(istream& is,CMatrix & m)
{is>>m.m_nRow>>m.m_nCol;m.Create(m.m_nRow,m.m_nCol);for(int i=0;i<m.m_nRow*m.m_nCol;i++){is>>m.m_pData[i];}return is;
}
4.拷贝构造函数
通过将一个已经存在的类的所有值拷贝从而赋予给一个新的类
CMatrix::CMatrix(const CMatrix & m):m_pData(NULL)
{*this = m;
}
这里注意一件事,我们构造的这个拷贝函数和原有的变量共享一个地址,这只能算是浅拷贝,意思就是当我们修改其中一个变量的值,其他变量也会改变。
三、析构函数的创建
当一个类变量的生命周期到了尽头之后,系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作,即释放内存,防止内存泄漏,当我们不写析构函数的时候,系统会自动替我们合成,但这样不确定性就影响着我们代码,所以一个完备的代码需要我们自己来完成析构函数的编写:
CMatrix::~CMatrix()
{Release();
}
void CMatrix::Release()
{if(m_pData){delete []m_pData;m_pData = NULL;}m_nRow = m_nCol = 0;
}
四、运算符的重载
加减乘除四则运算,在小数整数中都可以自由使用,但对于我们自己动手创造的类,程序并不知道加减乘除如何计算(如在线性代数中矩阵的乘法有他自己的一套规则),所以也需要我们自己通过对运算符进行重载来使得我们的类也可以进行加减
1、“ + ”, “+=” 号的重载
CMatrix& CMatrix::operator+=(const CMatrix& m)
{assert(m_nRow==m.m_nRow && m_nCol==m.m_nCol);for(int i=0;i<m_nRow*m_nCol;i++){m_pData[i]+=m.m_pData[i];}return *this;
}
CMatrix operator+(const CMatrix& m1,const CMatrix&m2)
{CMatrix m(m1);m += m2;return m;
}
2、关系运算符的重载
‘>’, ‘<’, '='运算符的重载
在定义大于小于符号的重定义之前,我们需要先定义一个值来表示变量的大小之分,这里我们使用矩阵所有值之和来表示他的大小:
CMatrix::operator double()
{double dSum=0;for(int i=0;i<m_nRow*m_nCol;i++){dSum+=m_pData[i];}return dSum;
}
bool operator > (CMatrix& m1, CMatrix& m2)
{return double(m1)>double(m2);
}
bool operator < (CMatrix& m1, CMatrix& m2)
{return double(m1)<double(m2);
}bool CMatrix::operator == (const CMatrix& m)
{if(!(m_nRow==m.m_nRow && m_nCol==m.m_nCol)){return false;}for(int i=0;i<m_nRow*m_nCol;i++){if(m_pData[i]!=m.m_pData[i]){return false;}}return true;
}
3、下标操作符的重载
既然是矩阵,我们就需要访问某些特定位置参数的功能,于是我们还需要进行 “[ ]”,"( )"这些函数功能的重载
double & CMatrix::operator[](int nIndex)
{assert(nIndex<m_nRow*m_nCol);return m_pData[nIndex];
}double & operator()(int nRow,int nCol)
{return m_pData[nRow*m_nCol+nCol];
}
4、赋值运算符的重载
CMatrix & CMatrix::operator=(const CMatrix & m)
{if(this==&m){return *this;}Create(m.m_nRow,m.m_nCol,m.m_pData);return *this;
}
五、输入和输出运输符:<<, >>的重载
就像java对每个类的toStrinfg()方法一样,我们同样需要定义类的如何向外输入和输出同时,由于需要访问私有变量,我们需要在定义函数的时候将他定义为友元函数
friend istream & operator>>(istream& is,CMatrix & m);
friend ostream & operator<<(ostream& os,const CMatrix &m);
istream & operator>>(istream& is,CMatrix & m)
{is>>m.m_nRow>>m.m_nCol;m.Create(m.m_nRow,m.m_nCol);for(int i=0;i<m.m_nRow*m.m_nCol;i++){is>>m.m_pData[i];}return is;
}
ostream & operator<<(ostream& os,const CMatrix &m)
{os<<m.m_nRow<<" "<<m.m_nCol<<endl;double * pData = m.m_pData;for(int i=0;i<m.m_nRow;i++){for(int j=0;j<m.m_nCol;j++){os<<*pData++<<" ";}os<<endl;}return os;
}
六、 运行测试代码
#include <iostream>
#include "ccomplex.h"
#include <stdio.h>
#include "cmatrix.h"
using namespace std;
int main(int argc, char *argv[])
{CMatrix m;double pData[10]={1,2,3,4,5,6};CMatrix m1(2,5,pData);{CMatrix m2(2,5);}CMatrix m3(m1);CMatrix ms[3] = {CMatrix(),CMatrix(2,5,pData),"d://1.tx"};CMatrix m4;m4 = m1;m1.Set(0,1,20);cout<<"m1=\n"<<m1;cout<<"m4=\n"<<m4;m4=m4;cout<<"after= m4=\n"<<m4;cout<<"m4[1]="<<m4[1];m4(0,1) = 4;m4+=m1;CMatrix m5;m5 = m4 + m1;double d = m5;cout<<"sum of m5="<<d;return 0;
}
实验结果:
m1=
2 5
1 20 3 4 5
6 0 0 0 0
m4=
2 5
1 2 3 4 5
6 0 0 0 0
after= m4=
2 5
1 2 3 4 5
6 0 0 0 0
m4[1]=2sum of m5=101
七、总结
通过本次自己手打一个完整的二维矩类,实现了各类构造器函数功能的编写,我学会了C++中面向对象编程中的各类代码书写规范,和public,friend,private,inline等各项修饰名词在C++中的各项作用。
但还是有很多不理解的地方,我会努力搞懂的!
实验1 CMatrix类设计与实现相关推荐
- C++程序设计:实验一 CMatrix类设计与实现
前言 在实验一当中,主要内容为CMatrix类的设计与实现,包含了CMatrix.h,CMatrix.cpp以及main.cpp三大文件. 文章目录 前言 一.实验要求: 1.构造函数 2.析构函数 ...
- [C++学习实验1]CMatrix类设计与实现
一.头文件创建 1.头文件定义了CMatrix类.类內部属性.函数.以及各种调用方法 头文件定义格式如下,属于条件编译宏定义,可以根据条件选择性的只编译某段程序,也可以防止重复定义. #ifndef ...
- C++学习记录 实验1 CMatrix类设计与实现
目录 一.源码实现 1.1 Main.cpp 1.2 CMatrix.cpp 1.3 CMatrix.h 二.知识小结 2.1 构造函数和析构函数 2.1.1 构造函数和析构函数的由来 2.1.2 构 ...
- C++ [实验一] CMatrix类设计与实现
目录 一.实验内容 二.代码实现 1.main.cpp 2.CMatrix.h 3.CMatrix.cpp 4.文本文件 1.txt 三.运行结果 四.代码分析 1.构造函数 2.析构函数 3.运算符 ...
- C++-实验一 CMatrix类设计
文章目录 前言 一.代码部分 1.Main函数 2.CMatrix.h 3.CMatrix.cpp 二.运行结果 三.总结 一. 构造和析构函数: 二. 运算符重载: 三. 友元函数: 前言 争取一周 ...
- C++ ——CMatrix类设计与实现
CMatrix类设计与实现 实验内容: 一.构造函数 1.CMatrix(): 不带参数的构造函数: 2.CMatrix(int nRow, int nCol, double *pData=NULL) ...
- C++ CMatrix类设计与实现
实验一:CMatrix类设计与实现 一 代码实现 1.main.cpp 2.CMatrix.h 3.CMatrix.cpp 二 运行截图 三 总结 1.构造函数 2.析构函数 3.运算符重载 4.友元 ...
- CMatrix类设计
文章目录 前言 一.实验内容 二.实现代码 1.main.cpp 2.CMatrix.h 3.CMatrix.h 4.运行结果 总结 前言 通过对CMatrix类的设计熟悉c++的类与对象,多态,构造 ...
- C++实验(一)—— CMatrix类设计与实现
目录 一.代码理解 CMatrix.h CMatrix.cpp Main.cpp 运行结果 二.总结 一.代码理解 CMatrix.h #ifndef CMATRIX_H //防止被重复引用 #def ...
最新文章
- Kmeans算法的过程是什么?Kmeans算法的缺陷主要有哪些?
- Data Mapper
- 要学习的别人的博客网址---收藏
- C++string类型与C语言字符数组的转换 std::string.c_str()函数
- 【2016年第6期】面向国际的生命组学大数据管理体系建设
- 信息学奥赛一本通(2054:【例3.4】适合晨练)
- 华为交换机命令_华为交换机故障诊断命令display怎么用?
- 2019 年的 Linux 会如何?
- 101个微软提供的Visual Studio 2005示例
- Restful API 的设计规范
- 为什么要有环回路由(zz)
- 运维服务级别管理流程
- Jaspersoft Studio 报表模板设计
- 牛!发出中国第一封电子邮件,注册登记域名CN,中国互联网之父传奇
- CentOS8离线安装mono
- 什么是服务器CC攻击,被CC攻击了服务器怎么防护?
- CorelDRAW常用工具之涂抹工具
- react报错Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
- error: cannot lock ref ‘refs/remotes/origin/douyin/open‘: ‘refs/remotes/origin/douyin‘ exists;
- CentOS 7 从下载到安装