栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

[C++实验1]CMatrix类设计与实现

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[C++实验1]CMatrix类设计与实现

一、头文件创建

1.头文件定义了CMatrix类、类內部属性、函数、以及各种调用方法

头文件定义格式如下,属于条件编译宏定义,可以根据条件选择性的只编译某段程序,也可以防止重复定义。

#ifndef CMATRIX_H
#define CMATRIX_H
//  具体的
//  头文件
//  正文内容

#endif 

二、有几类函数:

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中。

CMatrix的一个重载函数:当m_pData的空间不能容纳n_Row*n_Col时 m_pData=NULL

▲特点:
构造函数具有如下几个特点:

①名字与类名相同,可以有参数,但是不能有返回值(void也不行);
②作用是对对象进行初始化工作,如给成员变量赋值等;
③如果定义类时没有写构造函数,系统会生成一个默认的无参构造函数,默认构造函数没有参数,不做任何工作;
④如果定义了构造函数,系统不再生成默认的无参构造函数;
⑤对象生成时构造函数自动调用,对象一旦生成,不能在其上再次执行构造函数
一个类可以有多个构造函数,为重载关系。

其中:构造函数CMatrix的初始化有两种方式:
①在给变量分配空间时就直接赋值即可,这种方法初始化效率较高
②在分配空间之后再给变量赋值
值得注意的是,初始化时,变量的顺序必须和定义时变量的顺序一致
▲用法:

CMatrix::CMatrix()
{
    m_nRow = 0;
    m_nCol = 0;
    m_pData = NULL;
}


// 注意:传入参数的顺序和在类间定义时顺序一致
CMatrix::CMatrix():m_nRow(0), m_nCol(0), m_pData(0)
{
    // 初始化为NULL
}

// 有参构造函数
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;  // 因为这里的*this表示对象指针,赋值的是地址
}

// 对str对象操作
CMatrix::CMatrix(const char * strPath)
{
    m_pData = 0;
    m_nRow = m_nCol = 0;
    ifstream cin(strPath);  // 文件操作
    cin >> *this;
}

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

▲特点:

①析构函数名应与类名相同,只是在函数名前面加一个位取反符,以区别于构造函数。
②它不能带任何参数,也没有返回值(包括void类型)。由于没有函数参数,因此它不能被重载,只能有一个析构函数。
③如果用户没有编写析构函数,编译系统会自动生成一个缺省的析构函数(即使自定义了析构函数,编译器也总是会为我们合成一个析构函数,并且如果自定义了析构函数,编译器在执行时会先调用自定义的析构函数再调用合成的析构函数),它也不进行任何操作。所以许多简单的类中没有用显示的析构函数。
④当对象的生命周期结束时,撤销类对象时候会自动调用析构函数。
⑤对象在生命期结束,撤销类对象时会自动调用析构函数。
⑥如果用new运算动态地建立一个对象,那用delete运算符释放该对象时,才会调用析构函数。

▲用法:

// 析构函数,用于释放
CMatrix::~CMatrix()
{
        Release();
}


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

▲用法:

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);

 △运算符重载

// "="重载
CMatrix& CMatrix::operator = (const CMatrix& m)
{
        if(this!=&m)
        {
                Create(m.m_nRow, m.m_nCol, m.m_pData);
        }
        return *this;
}

// "=="重载
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& 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;
}

// "-="重载
CMatrix& CMatrix::operator -= (const CMatrix& m)
{
    assert(m_nRow==m.m_nRow && m_nCol==m.m_nCol);
    for (int i=0;i 

 △操作符重载 

// "[]"重载
double & CMatrix::operator[](int nIndex)
{
    //判定下标越界
    assert(nIndex>"重载
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_pData[i];
    }
    return is;
}

// "<<"重载
ostream & operator<<(ostream& os, const CMatrix &m)
{
    os<<"size:["< 

4.友元函数
输入和输出运输符:<<, >>

friend istream& operator>>(istream& is, CMatrix& m);
friend ostream& operator<<(ostream& os, const CMatrix& m);

①赋予特权,特殊声明,friend加了之后为全局函数不是成员函数,类里面定义的所有对象都可以调用,所以可以访问下面的private私有变量;
②输出输入流运算符重载,原本输出输入流只能针对基础的数据类型,比如char,int,double,指针,重载后使其能够读取自己定义的类。

5.主函数

#include 
#include 
#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("./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;
}

三、正文内容如下:

#ifndef CMATRIX_H
#define CMATRIX_H

#include

using namespace std;

class CMatrix
{
private:     //二维矩阵类变量定义
     int m_nRow;//行数
     int m_nCol;//列数
     double * m_pData=NULL;//用于存储矩阵中所有值地址的指针,初始化为NULL


public:
    CMatrix(); //构造器
    //如果nRow=0有默认值则之后的都得有默认值
    //若都默认值为0,相当于无参数,则会与上一个构造函数CMatrix();产生歧义,不知道调用哪一个
    //带行、列及数据指针等参数的构造函数, 并且参数带默认值

    CMatrix(int nRow, int nCol, double * pDate = NULL);  //拷贝构造函数
    CMatrix(const CMatrix& m);   //带文件路径参数的构造函数
    CMatrix(const char * strPah);
    ~CMatrix(); //析构函数


    bool Create(int nRow, int nCol, double* pDate);  //初始化
    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);
    bool operator == (const CMatrix& m);
    bool operator != (const CMatrix& m);

    //重载类型转换
    operator double();
};


// 重载运算符 "+"
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 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/395847.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号