C++面向对象程序设计-北京大学-郭炜【课程笔记(六)】

C++面向对象程序设计-北京大学-郭炜【课程笔记(六)】

  • 1、可变长数组类的实现
  • 2、流插入运算符和流提取运算符的重载
    • 2.1、对形如cout << 5 ; 单个"<<"进行重载
    • 2.2、对形如cout << 5 << “this” ;连续多个"<<"进行重载
    • 详解案例

毕业论文:学习速度较慢
开始课程:P19 4-4.可变长数组类的实现
课程链接:程序设计与算法(三)C++面向对象程序设计 北京大学 郭炜
课程PPT:github提供的对应课程PPT

本节课内容相对较难理解,只做两章。

1、可变长数组类的实现

此部分内容不好🦟解释:请听老师讲解,最好自己把代码敲一遍。
P19 4-4.可变长数组类的实现

// 17.cpp
# include<iostream>
using namespace std;
class CArray
{int size;   // 数组元素的个数int *ptr;   // 指向动态分配的数组public:CArray(int s=0);  // s代表数组元素的个数,构造函数CArray(CArray & a);~CArray();void push_back(int v);  // 用于在数组尾部添加一个元素vCArray & operator = (const CArray & a);  // 用于数组对象间的赋值,深拷贝int length() {return size;}  // 返回数组元素个数// int & CArray::operator[](int i)  // 返回值为int 不行!不支持a[i] = 4int & operator[](int i)  // 返回值为int 不行!不支持a[i] = 4,所以返回值定义为引用{// 用以支持根据下表访问数组元素,// 如n=a[i]和a[i]=4;这样的语句return ptr[i];}//非引用的函数返回值不可以作为左值使用
};// 构造函数
CArray::CArray(int s):size(s)
{if(s == 0)ptr = NULL;else    ptr = new int[s];  // 动态分配一个内存空间
}// 复制构造函数(防止数组地址冲突)
CArray::CArray(CArray & a)
{if(!a.ptr){ptr = NULL;size = 0;return ;}ptr = new int[a.size];memcpy(ptr, a.ptr, sizeof(int)*a.size);   //一共拷贝sizeof(int)*a.size字节的内容size = a.size;
}// 析构函数:释放动态内存空间
CArray::~CArray()
{// []:属于双目运算符if(ptr) delete [] ptr; //释放动态分配的内存空间// 释放之前判断一下ptr是不是空指针
}CArray & CArray::operator=(const CArray & a)
{// 赋值号的作用是使用“=”左边对象里存放的数组,大小和内容都和右边的对象一样,但是存储空间是不一样的;从而实现一种深拷贝if(ptr == a.ptr)  // 防止a=a这样的复制导致出错return * this;if(a.ptr == NULL){// 如果a里面的数组是空的if(ptr) delete [] ptr;ptr = NULL;size = 0;return *this;}if(size<a.size){// 如果原有空间够大,就不用单独分配内存空间了if(ptr){delete [] ptr;}ptr = new int[a.size];}memcpy(ptr, a.ptr, sizeof(int)*a.size);size = a.size;return * this;
}   // CArray & CArray::operator=(const CArray & a)void CArray::push_back(int v)
{// 在数组尾部添加一个元素if(ptr){int * tmpPtr = new int[size+1]; //重新分配空间,采用临时的指针tmpPtr存储memcpy(tmpPtr, ptr, sizeof(int)*size);  //拷贝原数组内容delete[] ptr;   // 删除原本的ptr空间ptr = tmpPtr;  // 将ptr指向刚才零时的指针}else   // 数组本来就是空的ptr = new int[1];ptr[size++] = v; // 加入新的数组元素
}// 要编写可变长整形数组类,使之能如下使用:
int main()
{CArray a;  // 开始这里的数组是空的for(int i=0; i < 5; ++i){a.push_back(i);     // 要用动态分配的内存来存放数组元素,需要一个指针成员变量}CArray a2, a3;a2 = a;    // 要重载“=”for(int i=0; i<a.length(); ++i){cout << a2[i] << " ";   // a2是一个对象名,不是数组名,对象名加中括号需要重载[]}a2 = a3;  // a2是空的for(int i=0; i<a2.length(); ++i)  // a2.length()返回0{cout << a2[i] << " ";}a2 = a3;cout << endl;a[3] = 100;CArray a4(a);  //CArray的复制构造函数for(int i=0; i<a4.length(); ++i){cout << a4[i] << "";}return 0;
}

Debug:最难听懂的一行代码:“=”运算符重载
a2 = a; // 要重载“=”
a2 = a3;
下面给出了debug图片可供理解。
请添加图片描述
请添加图片描述
在这里插入图片描述

2、流插入运算符和流提取运算符的重载

课程链接:5-5流插入运算符和流提取运算符的重载
配合下方代码解释仔细听课,即可听懂。

问题1:cout << 5 << “this”;为什么能够成立?
问题2:cout是什么?

  • cout 是在 iostream 中定义的,ostream 类
    的对象。

问题3:“<<” 为什么能用在 cout上?

  • “<<” 能用在cout 上是因为,在iostream里对 “<<” 进行了重载。

2.1、对形如cout << 5 ; 单个"<<"进行重载

cout << 5 ; 即 cout.operator<<(5); // 表示对cout这个对象调用operator<<这个成员函数
cout << “this”; 即 cout.operator<<( “this” );

// 有可能按以下方式重载成 ostream类的成员函数:
void ostream::operator<<(int n). // n:可以表示左移参数5
{…… //输出n的代码return;
}

2.2、对形如cout << 5 << “this” ;连续多个"<<"进行重载

考虑返回值的问题,如果返回值是void,那么cout还能接着往下运算吗?显然不可以,如果返回值是cout,那么就可以继续调用重载

ostream & ostream::operator<<(int s). // 返回值为ostream的引用
{
…… //输出n的代码
return * this;   // this指针指向了成员函数所作用的对象,那么其就是cout。那么返回值就是cout的引用(&cout)
}
ostream & ostream::operator<<( const char * s )
{
…… //输出s的代码
return * this;
}

cout << 5 << “this”; 本质上的函数调用的形式是什么?
cout.operator<<(5).operator<<(“this”);

详解案例

例题:假定c是Complex复数类的对象,现在希望写“cout << c;”,就能以“a+bi”的形式输出c的值,写“cin>>c;”,就能从键盘接受“a+bi”形式的输入,并且使得c.real = a,c.imag = b。

#include<iostream>
#include<string>
#include<cstdlib>using namespace std;class Complex
{double real, imag;public:Complex(double r=0, double i=0):real(r),imag(i) {};friend ostream & operator<<(ostream & os, const Complex & c);friend istream & operator>>(istream & is, Complex & c); 
};// cout是ostream的成员函数,所以我们不能去写成ostream的成员函数(已经封装好了),只能写成全局函数;
// 又因为需要访问稀有成员变量,所以要用到友元函数
// 操作数的个数等于这个函数的参数个数。可以为Complex的对象,也可以是Complex的引用(能够节省时间和空间)
// os为cout的引用,即ostream & os = cout;,所以os等于cout;那么返回值也是ostream & os;所以返回值等于cout
ostream & operator<<(ostream & os, const Complex & c)
{os << c.real << "+" << c.imag << "i" << "i";  // 以"a+bi"的形式输出return os;
}istream & operator>>(istream & is, Complex & c)
{string s;is >> s;  // 将"a+bi"作为字符串读入,"a+bi"中间不能有空格int pos = s.find("+", 0);string sTmp = s.substr(0, pos);  // 分离出代表实部的字符串c.real = atof(sTmp.c_str());// atof库函数能将const char*指针指向的内容转换为floatsTmp = s.substr(pos+1, s.length()-pos-2);// 分离出代表虚部的字符串c.imag = atof(sTmp.c_str());return is;
};int main()
{Complex c;int n;cin >> c >> n;  cout << c << "," << n;   return 0;
}//程序运行结果可以如下:
13.2+133i 87
13.2+133i, 87

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/815343.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯-最大子矩阵

问题描述 下面是一个 20x20 的矩阵&#xff0c;矩阵中的每个数字是一个1到9之间的数字&#xff0c;请注意显示时去除了分隔符号。 6985924183938786894117615876963131759284373473483266274834855367125655616786474316121686927432329479135474133499627734472797994592984…

⑤-1 学习PID--什么是PID

​ PID 算法可以用于温度控制、水位控制、飞行姿态控制等领域。后面我们通过PID 控制电机进行说明。 自动控制系统 在直流有刷电机的基础驱动中&#xff0c;如果电机负载不变&#xff0c;我们只要设置固定的占空比&#xff08;电压&#xff09;&#xff0c;电机的速度就会稳定在…

ceph rbd部署与使用

一、前言 Ceph RBD&#xff08;Rados Block Device&#xff09;是 Ceph 存储解决方案的一部分&#xff0c;它提供了一个分布式块设备服务&#xff0c;允许用户创建和管理虚拟块设备&#xff0c;类似于传统的本地磁盘&#xff0c;Ceph RBD 是一个高度可扩展的存储解决方案&#…

C语言:关于动态内存管理我到底应该懂些什么?看了我这篇你就通透了。

1.动态内存的分配 在我们初学C语言的时候&#xff0c;我们经常用一下几种方式申请内存空间。 int a 10;//在栈空间上开辟4个字节存放这个值。 char arr[10] {1,2,3,4,5,6,7,8,9,10};//在栈空间上开辟10个字节的连续空间。但是上述开辟空间有两个特点 1.空间开辟大小是固定的…

FJSP:袋鼠群优化(Kangaroo Swarm Optimization ,KSO)算法求解柔性作业车间调度问题(FJSP),提供MATLAB代码

一、柔性作业车间调度问题 柔性作业车间调度问题&#xff08;Flexible Job Shop Scheduling Problem&#xff0c;FJSP&#xff09;&#xff0c;是一种经典的组合优化问题。在FJSP问题中&#xff0c;有多个作业需要在多个机器上进行加工&#xff0c;每个作业由一系列工序组成&a…

微服务之Consul 注册中心介绍以及搭建

一、微服务概述 1.1单体架构 单体架构&#xff08;monolithic structure&#xff09;&#xff1a;顾名思义&#xff0c;整个项目中所有功能模块都在一个工程中开发&#xff1b;项目部署时需要对所有模块一起编译、打包&#xff1b;项目的架构设计、开发模式都非常简单。 当项…

C++ | Leetcode C++题解之第22题括号生成

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<string> res; //记录答案 vector<string> generateParenthesis(int n) {dfs(n , 0 , 0, "");return res;}void dfs(int n ,int lc, int rc ,string str){if( lc n && rc n…

美团笔试复盘

昨天做了美团的笔试&#xff0c;现在复盘一下。 1、将数组按照绝对值大小排序 有道算法题解决思路需要将数组按照绝对值大小进行排序&#xff0c;我使用的是sort方法Comparator比较器实现的&#xff0c;这里记录一下&#xff1a; public static void main(String[] args) {In…

第二证券策略:股指预计维持震荡格局 关注汽车、工程机械等板块

第二证券指出&#xff0c;指数自今年2月份阶段低点反弹以来&#xff0c;3月份持续高位整理。进入4月份之后面对年报和一季报的双重财报发表期&#xff0c;预计指数短期保持高位整理概率比较大。前期缺乏成绩支撑的概念股或有回落的危险&#xff0c;主张重视成绩稳定、估值低、分…

【Leetcode】1702. 修改后的最大二进制字符串

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 给你一个二进制字符串 b i n a r y binary binary &#xff0c;它仅有 0 0 0 或者 1 1 1 组成。你可以使用下面的操作任意次对它进行修改&#xff1a; 操作 1 &#xff1a;如果…

Golang(一):基础、数组、map、struct

目录 hello world 变量 常量&#xff0c;iota 函数 init函数和导包过程 指针 defer 数组和动态数组 固定长度数组 遍历数组 动态数组 len 和 cap 截取 切片的追加 map 四种声明方式 遍历map 删除 查看键是否存在 结构体 声明 作为形参 方法 封装 继承…

[入门到放弃]设计模式-笔记

模块化设计 20240448 模块不包含数据&#xff0c;通过实例的指针&#xff0c;实现对实例的操作&#xff1b;唯一包含的数据是用于管理这些模块的侵入式链表模块只负责更具定义的数据结构&#xff0c;执行对应的逻辑&#xff0c;实现不同实例的功能&#xff1b; 参考资料 使用…

【热门话题】常见分类算法解析

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 常见分类算法解析1. 逻辑回归&#xff08;Logistic Regression&#xff09;2. 朴…

4.Godot图片素材的获取和编辑

游戏开发中经常遇到图片素材的需求 1. 图片素材的准备 术语&#xff1a;Sprite 精灵&#xff0c;游戏开发中指一张图片来源不明的图片&#xff0c;切勿在商业用途使用&#xff0c;以免引起版权风险。 1. 在学习阶段&#xff0c;可以百度或者从一些资源网站获取&#xff0c;这…

ViT-DeiT:用于乳腺癌组织病理图像分类的集成模型

两种预训练Vision Transformer模型的集成模型&#xff0c;即Vision Transformer和数据高效视觉Transformer&#xff08;Data-Efficient Image Transformer&#xff09;。此集成模型是一种软投票模型。 近年来&#xff0c;乳腺癌的分类研究主要集中在超声图像分类、活检数据分类…

QT常用控件

常用控件 控件概述QWidget 核⼼属性核⼼属性概览enabledgeometrywindowTitlewindowIconwindowOpacitycursorfonttoolTipfocusPolicystyleSheet 按钮类控件Push ButtonRadio ButtionCheck Box 显⽰类控件LabelLCD NumberProgressBarCalendar Widget 输⼊类控件Line EditText Edi…

AI领域的最新动态:大型语言模型的崛起、AI芯片竞争与创新应用

AI领域的最新动态&#xff1a;大型语言模型的崛起、AI芯片竞争与创新应 在最近的AI新闻中&#xff0c;有几个重要的发展值得关注&#xff1a; 1. **大型语言模型的发布和更新**&#xff1a; - Google在其Google Cloud Next活动上宣布&#xff0c;Gemini 1.5现已在180多个国家/…

(学习日记)2024.04.15:UCOSIII第四十三节:任务消息队列

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

# 达梦sql查询 Sql 优化

达梦sql查询 Sql 优化 文章目录 达梦sql查询 Sql 优化注意点测试数据单表查询 Sort 语句优化优化过程 多表关联SORT 优化函数索引的使用 注意点 关于优化过程中工具的选用&#xff0c;推荐使用自带的DM Manage&#xff0c;其它工具在查看执行计划等时候不明确在执行计划中命中…

MySQL 主从复制部署(8.0)

什么是主从数据库 主从数据库是一种数据库架构模式&#xff0c;通常用于提高数据库的性能、可用性和可伸缩性。 它包括两种类型的数据库服务器&#xff1a; 1&#xff09;主数据库&#xff08;Master&#xff09;&#xff1a;主数据库是读写数据的主要数据库服务器。所有写操…