c++实验一

这篇博客详细介绍了C++实验的内容,包括构造函数的理解及其应用,析构函数的作用,运算符重载的原理与限制,友元函数的使用场景,以及内联函数的概念和好处。通过具体的代码示例和实验总结,深入探讨了这些关键概念。


一、实验内容

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 说明符。

内联函数的好处:编译的时候不是采用调用的方式,不用考虑入栈出栈,从而提高效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值