前言
通过对CMatrix类的设计熟悉c++的类与对象,多态,构造函数等。
提示:以下是本篇文章正文内容,下面案例可供参考
一、实验内容
????????一、构造函数 ? ? ? ? 1.CMatrix():?不带参数的构造函数; ? ? ? ? 2.CMatrix(int?nRow,?int?nCol,?double?*pData=NULL)?:?带行、列及数据指针等参数的构造函数,?并且参数带默认值; ? ? ? ? 3.CMatrix(const?char?*?strPath):?带文件路径参数的构造函数; ? ? ? ? 4.CMatrix(const?CMatrix&?m):?拷贝构造函数 ? ? ? ? 5.此外会用列表初始化成员变量:CMatrix():?m_nRow(0),?m_nCol(0),?m_pData(NULL); ? ? ? ? 6.bool?Create(int?nRow,?int?nCol,?double?*pData=NULL):?先删除原有空间,根据传入行列创建空间,如果pData不为空要将pData的内容拷贝到m_pData中。 ????????二、析构函数 ? ? ? ? 1.~CMatrix():?调用Release(); ? ? ? ? 2.Release():?将内存释放,并将行列设置为0; ????????三、运算符重载 ? ? ? ? 1.算术运算符重载:+,?-,?+=,?-= ? ? ? ? 2.关系运算符重载:>,?<,?== ? ? ? ? 3.下标操作符:[],?() ? ? ? ? 4强制类型转换:?double ? ? ? ? 5.赋值运算符:=,尤其注意当m1=m1特殊情况的处理 ????????四、友元函数 ????????输入和输出运输符:<<,?>>
二、实现过程
1.main.cpp
#include<iostream>
#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);
cout<<"CMatrix的对象有三个变量:m_nRow,m_nCol,m_pData"<<endl;
cin>>m1;
m2.Set(1,3,10);
cout<<m1;
cout<<m2;
CMatrix m3(m1);
cout<<m3<<endl;
CMatrix m4;
m4=m1;
m1.Set(0,1,20);
cout<<"m1="<<m1;
cout<<"m4="<<m4;
m4=m4;
cout<<"after is m4 =\n"<<m4<<endl;
m4(0,1)=4;
m4+=m1;
CMatrix m5;
m5=m4+m1;
int b=3.14;
double d=m5;
cout<<"m4="<<m4;
cout<<"sum of m="<<m5;
int i=int(d);
return 0;
}
2.CMatrix.h
#include<iostream>
#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);
cout<<"CMatrix的对象有三个变量:m_nRow,m_nCol,m_pData"<<endl;
cin>>m1;
m2.Set(1,3,10);
cout<<m1;
cout<<m2;
CMatrix m3(m1);
cout<<m3<<endl;
CMatrix m4;
m4=m1;
m1.Set(0,1,20);
cout<<"m1="<<m1;
cout<<"m4="<<m4;
m4=m4;
cout<<"after is m4 =\n"<<m4<<endl;
m4(0,1)=4;
m4+=m1;
CMatrix m5;
m5=m4+m1;
int b=3.14;
double d=m5;
cout<<"m4="<<m4;
cout<<"sum of m="<<m5;
int i=int(d);
return 0;
}
?
3.CMatrix.cpp
//<>编译器在系统文件目录下查找,“用户自定义”文件在当前文件所在目录下查找
#include"CMatrix.h"
#include<fstream> //引入文件操作头文件
#include<assert.h> //提供assert宏定义
CMatrix::CMatrix():m_nRow(0),m_nCol(0),m_pData(0) //使用初始化列表初始化字段
{
}
/*等同于
CMatrix::CMatrix() //使用初始化列表初始化字段,"::"表示作用域和所属关系,右边属于左边
{
m_nRow=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()
{
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!=NULL)
{
memcpy(m_pData,pData,nRow*nCol*sizeof(double));
}
return true;
}
void CMatrix::Release()
{
if(m_pData!=NULL)
{
delete []m_pData;
m_pData=NULL;
}
m_nRow=m_nCol=0;
}
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;
}
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;
}
运行结果
?
三、实验总结
一.构造函数和析构函数
1.构造函数的作用就是在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态。调用时无需提供参数的构造函数称为默认构造函数。构造函数由编译器自动调用,无需手动调用;没有返回值也不用写void,函数名称与类名相同,可以有参数,故可重载。
2.析构函数:与构造函数相反,当对象结束其生命周期,如对象所在的函数已调用完毕时,系统自动执行析构函数。析构函数往往用来做“清理善后”?的工作(例如在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)用“~”标识;没有返回值也不用写void,函数名称与类名相同,不可以重载。
二.运算符重载
1.运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。重载之后运算符的优先级和结合性不变;运算符重载的实质是函数重载。不能重载的运算符有:
(1)类属关系运算符“.”;(2)成员指针运算符“.*”;(3)作用域分辨符“::”;
(4)三目运算符“?:”
2.CMatrix::?operator?double()函数无需指明返回类型,double作为一个运算符,该函数用于double运算符重载。
3.this是指向自身对象的指针,*this是自身对象。也就是说return?*this返回的是当前对象的克隆或者本身(若返回类型为A,?则是克隆,?若返回类型为A&,?则是本身?)。return?this返回当前对象的地址(指向当前对象的指针)。
三.友元函数
1.引入友元函数的原因:类具有封装、继承、多态、信息隐藏的特性,只有类的成员函数才可以访问类的私有成员,非成员函数只能访问类的公有成员。为了使类的非成员函数访问类的成员,唯一的做法就是将成员定义为public,但这样做会破坏信息隐藏的特性。基于以上原因,引入友元函数解决。必须在类的说明中说明友元函数,说明时以关键字friend标识,后跟友元函数的函数原型,友元函数的说明可以出现在类的任何地方,包括private和public部分。
2.友元不是类的成员,不受类的声明区域public、private和protected的影响。友元函数不是类的成员函数,所以友元函数的实现与普通函数一样。在实现时不用“::”指示属于哪个类,只有成员函数才使用“::”作用域符号。友元函数不能直接访问类的成员,只能访问对象成员。
四.内联函数
1.增加了inline关键字的函数称为“内联函数”;降低了cpu的系统开销,使程序整体速度加快;循环、递归、代码过长都不适宜用内联函数。
注:调用内联函数的语句前必须已经出现内联函数的定义(即整个整体),而不能只出现内联函数的声明。
????????
|