目录

  • 一、源码实现
    • 1.1 Main.cpp
    • 1.2 CMatrix.cpp
    • 1.3 CMatrix.h
  • 二、知识小结
    • 2.1 构造函数和析构函数
      • 2.1.1 构造函数和析构函数的由来
      • 2.1.2 构造函数和析构函数的基本语法
      • 2.1.3 构造函数的分类和调用
      • 2.1.4 构造函数和析构函数的小结
    • 2.2 友元函数
      • 2.2.1 什么是友元函数
      • 2.2.2 使用友元函数的优缺点
      • 2.2.3 语法
    • 2.3 运算符重载
      • 2.3.1 运算符重载的概念理解如果不做特殊处理,C++ 的 +、-、*、/ 等运算符只能用于对基本类型的常量或变量进行运算,不能用于对象之间的运算。
      • 2.3.2 运算符重载为友元函数

一、源码实现

1.1 Main.cpp

#include<iostream>
using namespace std;
#include"CMatrix.h"
int main()
{double pData[10] = { 2,3,4,5 };CMatrix m1, m2(2, 5, pData);cin >> m1;m2.Set(1, 3, 10);cout << m1 << m2;CMatrix ms[4] = { CMatrix(),CMatrix(2,5,pData),CMatrix(ms[1]),CMatrix("C:\\1.txt") };cout << ms[1] << ms[2];if (ms[1] != ms[2]){cout << "Error occur!" << endl;}ms[1] += ms[2];ms[1][1] = 100;ms[1](1, 1) = 50;cout << ms[1];cout << "sum of m1=" << double(ms[1]);double d = 1.2;int i = int(d);return 0;
}

1.2 CMatrix.cpp

#include "CMatrix.h"
#include<fstream>
#include<assert.h>
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){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;
}
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 + 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.3 CMatrix.h

#pragma once
#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 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;
}

运行结果:

图1.1

二、知识小结

2.1 构造函数和析构函数

2.1.1 构造函数和析构函数的由来

类的数据成员不能在类的声明时候初始化,为了解决这个问题? 使用构造函数处理对对象的初始化。构造函数是一种特殊的成员函数,与其他函数不同,不需要用户调用它,而是创建对象的时候自动调用。析构函数是对象不再使用的时候,需要清理资源的时候调用。

2.1.2 构造函数和析构函数的基本语法

  • A.构造函数

    • C++中的类需要定义与类名相同的特殊成员函数时,这种与类名相同的成员函数叫做构造函数;
    • 构造函数可以在定义的时候有参数;
    • 构造函数没有任何返回类型;
    • 构造函数的调用: 一般情况下,C++编译器会自动的调用构造函数。特殊情况下,需要手工的调用构造函数。
class Test
{public://构造函数Test(){}
}
  • B.析构函数

    • C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的函数是析构函数;
    • 析构函数没有参数和没有任何返回类型;
    • 析构函数在对象销毁的时候自动调用;
    • 析构函数调用机制: C++编译器自动调用。
class Test
{~Test(){}
}

2.1.3 构造函数的分类和调用

  • A.无参构造函数
class Test
{private:int x;public:Test(){this->x=10;}
}
- Test a(10); 调用有参数构造函数
  • B.有参构造函数
class Test
{private:int x;public:Test(int x){this->x=x;}
}

有参数构造函数的调用时机:

- Test a(10); 调用有参数构造函数
- Test b=(2,3); 逗号表达式的值是最后一位,调用有参数构造函数
- Test c=Test(2); 产生一个匿名对象,直接转化成c(只会调用一次有参数构造函数)

2.1.4 构造函数和析构函数的小结

a. 构造函数时C++中用于初始化对象状态的特殊函数;
b. 构造函数在对象创建的时候自动调用;
c. 构造函数和普通成员函数都遵循重载原则;
d. 拷贝构造函数是对象正确初始化的重要保障;
e. 必要的时候必须手工的写拷贝构造函数。

2.2 友元函数

2.2.1 什么是友元函数

在实现类之间数据共享时,减少系统开销,提高效率。如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数。
具体来说:为了使其他类的成员函数直接访问该类的私有变量。即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数。

2.2.2 使用友元函数的优缺点

优点:能够提高效率,表达简单、清晰。

缺点:友元函数破环了封装机制,尽量不使用成员函数,除非不得已的情况下才使用友元函数。

2.2.3 语法

声明: friend + 普通函数声明

实现位置:可以在类外或类中

实现代码:与普通函数相同

调用:类似普通函数,直接调用

2.3 运算符重载

2.3.1 运算符重载的概念理解如果不做特殊处理,C++ 的 +、-、*、/ 等运算符只能用于对基本类型的常量或变量进行运算,不能用于对象之间的运算。

有时希望对象之间也能用这些运算符进行运算,以达到使程序更简洁、易懂的目的。例如,复数是可以进行四则运算的,两个复数对象相加如果能直接用+运算符完成,这样显得很直观和简洁。
利用 C++ 提供的“运算符重载”机制,赋予运算符新的功能,就能解决用+将两个复数对象相加这样的问题。
运算符重载,就是对已有的运算符赋予多重含义,使同一运算符作用于不同类型的数据时产生不同的行为。运算符重载的目的是使得 C++ 中的运算符也能够用来操作对象。
运算符重载的实质是编写以运算符作为名称的函数。不妨把这样的函数称为运算符函数。运算符函数的格式如下:

返回值类型  operator  运算符(形参表)
{....
}

2.3.2 运算符重载为友元函数

一般情况下,将运算符重载为类的成员函数是较好的选择。但有时,重载为成员函数不能满足使用要求,重载为全局函数又不能访问类的私有成员,因此需要将运算符重载为友元。

例如,对于复数类 Complex 的对象,希望它能够和整型以及实数型数据做四则运算,假设 c 是 Complex 对象,希望c+5和5+c这两个表达式都能解释得通。

将+重载为 Complex 类的成员函数能解释c+5,但是无法解释5+c。要让5+c有意义,则应对+进行再次重载,将其重载为一个全局函数。为了使该全局函数能访问 Complex 对象的私有成员,就应该将其声明为 Complex 类的友元。具体写法如下:

class Complex
{double real, imag;
public:Complex(double r, double i):real(r), imag(i){};Complex operator + (double r);friend Complex operator + (double r, const Complex & c);
};
Complex Complex::operator + (double r)
{ //能解释c+5return Complex(real+r, imag);
}
Complex operator + (double r, const Complex & c)
{ //能解释5+creturn Complex (c.real+r, c.imag);
}

本次实验中,通过构造函数,析构函数,运算符重载和友元函数四个方面进行了设计,通过实战,掌握了以上知识点。

C++学习记录 实验1 CMatrix类设计与实现相关推荐

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

    一.头文件创建 1.头文件定义了CMatrix类.类內部属性.函数.以及各种调用方法 头文件定义格式如下,属于条件编译宏定义,可以根据条件选择性的只编译某段程序,也可以防止重复定义. #ifndef ...

  2. C++程序设计:实验一 CMatrix类设计与实现

    前言 在实验一当中,主要内容为CMatrix类的设计与实现,包含了CMatrix.h,CMatrix.cpp以及main.cpp三大文件. 文章目录 前言 一.实验要求: 1.构造函数 2.析构函数 ...

  3. C++ [实验一] CMatrix类设计与实现

    目录 一.实验内容 二.代码实现 1.main.cpp 2.CMatrix.h 3.CMatrix.cpp 4.文本文件 1.txt 三.运行结果 四.代码分析 1.构造函数 2.析构函数 3.运算符 ...

  4. C++-实验一 CMatrix类设计

    文章目录 前言 一.代码部分 1.Main函数 2.CMatrix.h 3.CMatrix.cpp 二.运行结果 三.总结 一. 构造和析构函数: 二. 运算符重载: 三. 友元函数: 前言 争取一周 ...

  5. 实验1 CMatrix类设计与实现

    一.头文件的创建 C++对于创建一个类以及各项方法的推荐做法是在头文件.h中将类中所有的函数,变量预先定义,之后再在另一个.cpp文件中将这些所有方法一一实现,所以我们需要将我们对于矩阵类(我们之后都 ...

  6. C++ ——CMatrix类设计与实现

    CMatrix类设计与实现 实验内容: 一.构造函数 1.CMatrix(): 不带参数的构造函数: 2.CMatrix(int nRow, int nCol, double *pData=NULL) ...

  7. C++ CMatrix类设计与实现

    实验一:CMatrix类设计与实现 一 代码实现 1.main.cpp 2.CMatrix.h 3.CMatrix.cpp 二 运行截图 三 总结 1.构造函数 2.析构函数 3.运算符重载 4.友元 ...

  8. CMatrix类设计

    文章目录 前言 一.实验内容 二.实现代码 1.main.cpp 2.CMatrix.h 3.CMatrix.h 4.运行结果 总结 前言 通过对CMatrix类的设计熟悉c++的类与对象,多态,构造 ...

  9. C++实验(一)—— CMatrix类设计与实现

    目录 一.代码理解 CMatrix.h CMatrix.cpp Main.cpp 运行结果 二.总结 一.代码理解 CMatrix.h #ifndef CMATRIX_H //防止被重复引用 #def ...

最新文章

  1. 递归遍历Linux下的目录文件源码实现
  2. 面试问:Kafka 为什么速度那么快?
  3. 【图嵌入】DeepWalk原理与代码实战
  4. spring-jar包详解整理
  5. 水晶报表技术(3)——.NET 2005 中动态水晶报表的实现
  6. 代理服务器有问题怎么办?
  7. java丶对数组值按首字母进行排序
  8. 同城聚合平台v59.2.0 本地同城 同城信息 同城商家
  9. 计算机影响因子10.0什么水平,论文的影响因子是什么?由什么决定?_1 论文影响因子10.0什么水平...
  10. 如何优雅的用Axure绘制高保真原型心得分享
  11. 解密mysql导出的ncx文件内的加密密码
  12. 数据库逻辑设计之三大范式通俗理解
  13. Ubuntu 12.04 LTS 64bit 下安装 jdk-6u43-linux-x64.bin的步骤
  14. [译]搜索与优化不存在免费的午餐
  15. 播放器音乐源之天天动听API
  16. 深度学习之SSD总结
  17. 单级放大器1db压缩点 matlab仿真,0.1db压缩点
  18. 论我的dfs经验总结
  19. 〖大前端 - 基础入门三大核心之CSS篇⑯〗- 相对定位、绝对定位 与 固定定位
  20. php循环奇,php – javascript循环奇/偶数组

热门文章

  1. 笔记本重装后回收站文件怎么恢复
  2. docker常用命令 | game2048网页游戏 | nginx镜像 | 数据卷管理 | docker网络管理 | 构建apache镜像 | Dockerfile常用的命令
  3. 利用java的网络编程实现一个小游戏(类似于石头剪刀布)
  4. 一个程序猿面试的毒鸡汤
  5. C语言编译器概要设计思路一
  6. VaR(value at risk)在险价值
  7. 2021音视频集成展已启幕,视通科技邀您云上参展 !
  8. stm32 PWM中的频率、占空比计算的总结
  9. pdf转换器4.1下载?
  10. 【学习日记】突发奇想