文章目录
一、实验内容
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.Ccomplex.h
#ifndef CMATRIX_H
#define CMATRIX_H
#include <iostream>
using namespace std;
class CMatrix
{
public:
CMatrix();
CMatrix(int nRow,int nCol,double *pData=NULL);
CMatrix(const CMatrix& m);
CMatrix(const char * strPath);
~CMatrix();//析构函数
bool Create(int nRow,int nCol,double *pData=NULL);
void Set(int nRow,int nCol,double dVale);
void Release();//释放内存
//加friend 依然是全局函数不是成员函数,为了解决私有变量保护的问题
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);
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
2.Ccomplex.ccp
#include "CMatrix.h"
#include <fstream>
#include <assert.h>
CMatrix::CMatrix():m_nRow(0),m_nCol(0),m_pData(0)
//申请空间后初始化 顺序不能变 效率更高初始化时立刻做掉
{
}
CMatrix::CMatrix(int nRow,int nCol,double *pData):m_pData(0)
{
Create(nRow,nCol,pData);
}
CMatrix::CMatrix(const CMatrix& m):m_pData(0)
{
*this =m;
}
CMatrix::CMatrix(const char * strPath)
{
m_pData = 0;
m_nRow = m_nCol = 0;
ifstream cin(strPath);
cin>>*this;//就是指的是CMatrix对象的地址/指针(加上*就是对象)
}
CMatrix::~CMatrix()
{
Release();//其实这里跟释放内存的代码是一样的,考虑到防止错误和代码维护
}
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));
}
}
void CMatrix::Release()//释放内存
{
if(m_pData)
{
delete []m_pData;
m_pData = NULL; }
m_nRow = m_nCol = 0;
}
CMatrix& CMatrix::operator=(const CMatrix& m) {
if(this!=&m){
Create(m.m_nRow,m.m_nCol,m.m_pData);
}
return *this;
}
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 m3(m1);
m3 += m2;
return m3;
}
double & CMatrix::operator[](int nIndex)
{
assert(nIndex<m_nRow*m_nCol);
return m_pData[nIndex];
}
double & CMatrix::operator()(int nRow,int nCol) {
assert(nRow*m_nCol+nCol<m_nRow*m_nCol);
return m_pData[nRow*m_nCol+nCol];
}
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;
}
bool CMatrix::operator !=(const CMatrix& m) {
return !((*this)==m);
}
CMatrix::operator double()
{
double dS=0;
for(int i=0;i<m_nRow*m_nCol;i++)
{
dS+=m_pData[i];
}
return dS;
}
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;
}
3.main.cpp
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause")*/
#include "CComplex.h"
#include <stdio.h>
#include "CMatrix.h"
using namespace std;
int main(int argc, char *argv[]) {
double pData[10]={2,3,4,5};
CMatrix m1,m2(2,5,pData), m3("D:\\1.txt"),m4(m2);
cin>>m1;
m2.Set(1,3,10);//内联函数的好处:编译的时候不是采用调用的方式,不用考虑入栈出栈,从而提高效率
cout<<m1<<m2<<m3<<m4;
m4=m3;
m4[2]=m4+1;
if(m4==m3)
{
cout<<"Error !"<<endl;
}
m4 += m3;
cout<<"sum of m4 = "<<(double)m4<<endl;
return 0;
}
4.测试与结果截图
输入:

输出:

实验总结
1.构造函数
个人理解的构造函数就是相当于一个人身兼多职,可以穿上不一样的工作服从而可以有多种特定形式。
例如此次试验有不带参数的构造函数(即为默认构造函数),如果需要,构造函数也可以带有参数。这样在创建对象时就会给对象赋初始值。
新学了带文件路径参数的构造函数、带行、列及数据指针等参数的构造函数, 并且参数带默认值,甚至还有拷贝构造函数。
2.析构函数
类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。
析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
注:写一个专门的删除功能函数,可以多次用。其实这里跟释放内存的代码是一样的,考虑到防止错误和代码维护
3.运算符重载
1.运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。重载之后运算符的优先级和结合性不变;运算符重载的实质是函数重载。不能重载的运算符有:
(1)类属关系运算符“.”;(2)成员指针运算符“.*”;(3)作用域分辨符“::”;
(4)三目运算符“?:”
2.CMatrix:: operator double()函数无需指明返回类型,double作为一个运算符,该函数用于double运算符重载。
3.this//就是指的是CMatrix对象的地址/指针(加上*就是对象)。
4.友元函数
有些情况下,允许特定的非成员函数访问一个类的私有成员,同时仍阻止一般的访问,这是很方便做到的。例如被重载的操作符,如输入或输出操作符,经常需要访问类的私有数据成员。
友元(frend)机制允许一个类将对其非公有成员的访问权授予指定的函数或者类,友元的声明以friend开始,它只能出现在类定义的内部,友元声明可以出现在类中的任何地方:友元不是授予友元关系的那个类的成员,所以它们不受其声明出现部分的访问控制影响。通常,将友元声明成组地放在类定义的开始或结尾是个好主意。
5.内联函数
什么是内联函数?工程中提到:
C++ 内联函数是通常与类一起使用。如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。
对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编译器需要重新更换一次所有的代码,否则将会继续使用旧的函数。
如果想把一个函数定义为内联函数,则需要在函数名前面放置关键字 inline,在调用函数之前需要对函数进行定义。如果已定义的函数多于一行,编译器会忽略 inline 限定符。
在类定义中的定义的函数都是内联函数,即使没有使用 inline 说明符。
内联函数的好处:编译的时候不是采用调用的方式,不用考虑入栈出栈,从而提高效率。
这篇博客详细介绍了C++实验的内容,包括构造函数的理解及其应用,析构函数的作用,运算符重载的原理与限制,友元函数的使用场景,以及内联函数的概念和好处。通过具体的代码示例和实验总结,深入探讨了这些关键概念。

848

被折叠的 条评论
为什么被折叠?



