C++ 《类与对象》(中下)

C++ 《类与对象》(下)

  • 赋值运算符重
    • 运算符定义
  • 取地址运算符重载
    • const成员函数
  • 初始化列表
    • 格式
    • 练习
  • 类型转换
  • 结束!!!!

赋值运算符重

• 当运算符被⽤于类类型的对象时,C++语⾔允许我们通过运算符重载的形式指定新的含义。C++规
定类类型对象使⽤运算符时,必须转换成调⽤对应运算符重载,若没有对应的运算符重载,则会编
译报错。

运算符定义

运算符重载是具有特名字的函数,他的名字是由operator和后⾯要定义的运算符共同构成。和其他函数⼀样,它也具有其返回类型和参数列表以及函数体。

int operator+int x,int y);//声明
int operator+int x,int y)//定义
{return x+y;
}

但是关于运算符重载函数的声明与定义一定的要求:

// 重载为全局的⾯临对象访问私有成员变量的问题
// 有⼏种⽅法可以解决:
// 1、成员放公有
// 2、Date提供getxxx函数
// 3、友元函数
// 4、重载为成员函数

1.成员公有

#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
//private://公开成员
int _year;
int _month;
int _day;
};

2.Date提供getxxx函数

#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}int& get()//用这个get函数返回这个类的成员
{return _day;
}
//private://公开成员
int _year;
int _month;
int _day;
};int operator+(int x,int y);
int operator+int x,int y)
{Date A; return A.get()+y
}

3.友元函数

#include<iostream>
using namespace std;
class Date
{
friend int operator+(int x,int y);//友元函数
public:
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};int operator+(int x,int y);
int operator+int x,int y)
{return x+y;
}

4.重载为成员函数

#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
int operator+(int x,int y);//成员函数
private:
int _year;
int _month;
int _day;
};
int operator+int x,int y)//定义
{return x+y;
}

• 重载运算符函数的参数个数和该运算符作⽤的运算对象数量⼀样多。⼀元运算符有⼀个参数,⼆元运算符有两个参数,⼆元运算符的左侧运算对象传给第⼀个参数,右侧运算对象传给第⼆个参数。

class Date
比特就业课
{
public:
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
Date(const Date& d)
{
cout << " Date(const Date& d)" << endl;
_year = d._year;
_month = d._month;
_day = d._day;
}
// 传引⽤返回减少拷⻉
// d1 = d2;
Date& operator=(const Date& d)//对应了元运算符有⼀个参数,⼆元运算符有两个参数,⼆元运算符的左侧运算对象传给第⼀个参数,右侧运算对象传给第⼆个参数
{
// 不要检查⾃⼰给⾃⼰赋值的情况
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
// d1 = d2表达式的返回对象应该为d1,也就是*this
return *this;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};

取地址运算符重载

const成员函数

将const修饰的成员函数称之为const成员函数,const修饰成员函数放到成员函数参数列表的后
⾯。
• const实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进⾏修改。
const 修饰Date类的Print成员函数,Print隐含的this指针由 Date* const this 变为 const
Date* const this

public:
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
// void Print(const Date* const this) const
void Print() const
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
// 这⾥⾮const对象也可以调⽤const成员函数是⼀种权限的缩⼩
Date d1(2024, 7, 5);
d1.Print();
const Date d2(2024, 8, 5);
d2.Print();
return 0;
}

初始化列表

之前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅
式,就是初始化列表,初始化列表的使⽤⽅式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成
员列表,每个"成员变量"后⾯跟⼀个放在括号中的初始值或表达式。

格式

1、每个成员变量在初始化列表中只能出现⼀次,语法理解上初始化列表可以认为是每个成员变量定义初始化的地⽅。
2、引⽤成员变量,const成员变量,没有默认构造的类类型变量,必须放在初始化列表位置进⾏初始化,否则会编译报错。

public:
Date(int& x,int year = 1, int month = 1, int day = 1)//初始化列表_year(year)
,_month(month)_day(day)
,_n(1)
,_ref(x)
{}
// void Print(const Date* const this) const
void Print() const
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
const int _n;//常量
int& _ref;//引用
Time _t; // 没有默认构造
};

3、C++11⽀持在成员变量声明的位置给缺省值,这个缺省值主要是给没有显⽰在初始化列表初始化的成员使⽤的。

class Date
{
public:
Date()
:_month(2)
{
cout << "Date()" << endl;
}
void Print() const
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
// 注意这⾥不是初始化,这⾥给的是缺省值,这个缺省值是给初始化列表的
// 如果初始化列表没有显⽰初始化,默认就会⽤这个缺省值初始化
int _year = 1;
int _month = 1;
int _day;
Time _t = 1;
const int _n = 1;
int* _ptr = (int*)malloc(12);
};

4、尽量使⽤初始化列表初始化,因为那些你不在初始化列表初始化的成员也会⾛初始化列表,如果这个成员在声明位置给了缺省值,初始化列表会⽤这个缺省值初始化。如果你没有给缺省值,对于没有显⽰在初始化列表初始化的内置类型成员是否初始化取决于编译器,C++并没有规定。对于没有显⽰在初始化列表初始化的⾃定义类型成员会调⽤这个成员类型的默认构造函数,如果没有默认构造会编译错误。

5、初始化列表中按照成员变量在类中声明顺序进⾏初始化,跟成员在初始化列表出现的的先后顺序⽆关。建议声明顺序和初始化列表顺序保持⼀致。

练习

下⾯程序的运⾏结果是什么()
A. 输出 1 1
B. 输出 2 2
C. 编译报错
D. 输出 1 随机值
E. 输出 1 2
F. 输出 2 1

#include<iostream>
using namespace std;
class A
{
public:
A(int a)
:_a1(a)
, _a2(_a1)
{}
void Print() {
cout << _a1 << " " << _a2 << endl;
}
private:
int _a2 = 2;
int _a1 = 2;
};
int main()
{
A aa(1);
aa.Print();
}

这里考点为:**初始化列表中按照成员变量在类中声明顺序进⾏初始化,跟成员在初始化列表出现的的先后顺序⽆关。建议声明顺序和初始化列表顺序保持⼀致。因为_a2先声明,所以_a2就先初始化,但是由于_a2(_a1),_a1还没初始化,导致_a2成随机值.,所以选 D

类型转换

C++⽀持内置类型隐式类型转换为类类型对象,需要有相关内置类型为参数的构造函数、
构造函数前⾯加explicit就不再⽀持隐式类型转换

#include<iostream>
using namespace std;
class A
{
public:
// 构造函数explicit就不再⽀持隐式类型转换
// explicit A(int a1)
A(int a1)
:_a1(a1)
{}
//explicit A(int a1, int a2)
A(int a1, int a2)
:_a1(a1)
,_a2(a2)
{}
void Print()
{
cout << _a1 << " " << _a2 << endl;
}
private:
int _a1 = 1;
int _a2 = 2;
};
int main()
{
// 1构造⼀个A的临时对象,再⽤这个临时对象拷⻉构造aa3
// 编译器遇到连续构造+拷⻉构造->优化为直接构造
A aa1 = 1;//类型转换,用1先构造在拷贝构造,之后被优化为构造
aa1.Print();
const A& aa2 = 1;
// C++11之后才⽀持多参数转化
A aa3 = { 2,2 };
return 0;
}

结束!!!!

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

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

相关文章

立元科技-Java面经

面试时间&#xff1a;2024年2月13日 面试地点&#xff1a;线下 面试流程&#xff1a;一轮面试 首先写了点笔试题&#xff0c;但是人家根本不看&#xff08;这个也就一面&#xff09; &#xff08;聊的还行&#xff0c;但是公司环境不是特别的好&#xff0c;一次面试&#x…

挖掘IPython的深度:%%dhist命令的历史探索之旅

挖掘IPython的深度&#xff1a;%%dhist命令的历史探索之旅 IPython&#xff0c;作为一款强大的交互式Python解释器&#xff0c;不仅提供了丰富的功能来增强Python编程体验&#xff0c;还允许用户轻松地回顾和利用历史命令。%%dhist命令是IPython中一个非常实用的魔术命令&…

【数据分享】2008-2022年我国省市县三级的逐日NO2数据(excel\shp格式)

空气质量数据是在我们日常研究中经常使用的数据&#xff01;之前我们给大家分享了2000-2022年的省市县三级的逐日PM2.5数据、2013-2022年的省市县三级的逐日CO数据和2013-2022年的省市县三级的逐日SO2数据&#xff08;均可查看之前的文章获悉详情&#xff09;&#xff01; 本次…

CrossEntropyLoss交叉熵损失函数的使用

目录 CrossEntropyLoss交叉熵损失函数的使用&#xff1a; 一、官方说明&#xff1a; 二、两种使用情况&#xff1a; 1&#xff09;情况一&#xff1a;target是一个类索引&#xff08;Example of target with class indices&#xff09; 2&#xff09;情况二&#xff1a;tar…

LeeCode Practice Journal | Day23_Backtracking

39.组合总和 题目&#xff1a;39. 组合总和 - 力扣&#xff08;LeetCode&#xff09; 题解&#xff1a;代码随想录 (programmercarl.com) 不同要求下的组合&#xff0c;可以进行一下总结 solution public class Solution {public List<IList<int>> results new…

Postman API测试数据生成秘籍:技巧与实践

Postman API测试数据生成秘籍&#xff1a;技巧与实践 在API测试过程中&#xff0c;生成合适的测试数据是确保测试覆盖率和准确性的关键步骤。Postman作为流行的API开发和测试工具&#xff0c;提供了多种方法来生成和管理测试数据。本文将深入探讨Postman中API测试数据生成的技…

jmeter实战(1)- Mac环境安装

一、安装 JDK 这个就不介绍了&#xff0c;本地自行安装 JDK 并且配置好环境变量 二、安装 Jmeter 1. 下载地址 —> 下载链接点击这里 2. 选择合适的版本下载 3. 解压到本地目录 解压后&#xff0c;会得到下面的目录文件&#xff1a; 输入cd bin&#xff0c;进入到bin…

Java中的多级缓存设计与实现

Java中的多级缓存设计与实现 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在现代应用程序中&#xff0c;多级缓存设计是一种常见的性能优化技术。多级缓存通过在不同层次上缓存数据来减少对底层存…

[STM32]HAL库实现自己的BootLoader-BootLoader与OTA-STM32CUBEMX

目录 一、前言 二、BootLoader 三、BootLoader的实现 四、APP程序 五、效果展示 六、拓展 一、前言 听到BootLoader大家一定很熟悉&#xff0c;在很多常见的系统中都会存在BootLoader。本文将介绍BootLoader的含义和简易实现&#xff0c;建议大家学习前掌握些原理基础。 …

目标检测算法:基本原理、发展历程、主要方法以及未来的发展趋势。

目标检测算法&#xff0c;作为计算机视觉领域中的一项关键技术&#xff0c;近年来得到了广泛的关注和研究。它旨在从图像或视频中准确地识别出目标的位置和类别&#xff0c;对于实现图像理解、视频分析、智能监控等应用具有重要意义。本文将详细介绍目标检测算法的基本原理、发…

实时更新UI界面

1.处理实时通信&#xff0c;几种方案 1&#xff1a;当一个用户发送一条需要实时更新的信息&#xff0c;我可以直接查找在线用户&#xff0c;通过在线用户来进行判断条件&#xff0c;发送更新请求 2&#xff1a;用户在一个需要实时更新的界面时&#xff0c;就不断的向服务端发…

【Android】Activity与Fragment的数据传递

上一篇文章学到了碎片的创建与生命周期&#xff0c;接下来学习碎片的常用操作&#xff0c;其中会用到上一篇文章的三个碎片&#xff0c;就做一个简单的说明吧&#xff1a;LeftFragment&#xff08;包含一个按钮&#xff09;、RightFragment4&#xff08;以粉色为背景的文本&…

408专业课130|零基础五个月速成攻略

计算机考研&#xff0c;有两个选择&#xff0c;一个是自命题&#xff0c;一个是408。如果你只是考一个普通院校&#xff0c;可以选择考自命题院校&#xff0c;容易上岸&#xff0c;但是如果考985/211/这类院校&#xff0c;最好还是选择408&#xff0c;因为408的考风险能力很强&…

Apollo部署与简易架构梳理

文章目录 apollo 安装apollo的基本架构组件机制component编译与加载 节点通讯数据的传输消息读写的实现消息的写端消息读端 常用术语ComponentChannelTaskNodeReader/WriterService/ClientParameter服务发现CRoutineSchedulerMessageDag文件Launch文件Record文件Mainboard Moni…

在图神经网络(GNN)上进行关系推理的新架构

开发能够学习推理的模型是一个众所周知的具有挑战性的问题&#xff0c;在这个领域中&#xff0c;使用图神经网络&#xff08;GNNs&#xff09;似乎是一个自然的选择。然而&#xff0c;以往关于使用GNNs进行推理的工作表明&#xff0c;当这些模型面对需要比训练时更长推理链的测…

JS代码混淆

JavaScript Obfuscator是JavaScript的功能强大的免费混淆器&#xff0c;其中包含多种功能&#xff0c;可为您的源代码提供保护&#xff0c;它支持很多流行的前端打包工具&#xff0c;如Webpack、Gulp、Grunt等都有相应的插件。 主要特征&#xff1a; ∙变量重命名 ∙字符串提…

(leetcode学习)236. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以是它自己的祖…

有一个动态数组a,约束如下:a的元素在5-10之间;a.sum小于100。 问:为什么随机出来的a绝对值都很大?如何解决这一问题?

题目 有一个动态数组a&#xff0c;约束如下&#xff1a;a的元素在5-10之间&#xff1b;a.sum小于100。 问&#xff1a;为什么随机出来的a绝对值都很大&#xff1f;如何解决这一问题&#xff1f; … int a[]; constraint c1{ a.size() inside [5:10]; a.sum() inside [0:100…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第五十一章 添加设备树节点

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

linux禁用root

linux禁用root 1. 禁止普通用户切换到root1.1 sudo -i和sudo -s的区别1.2 sudo -i和直接登录root账号的区别1.3 禁止sudo -i切换root1.4 禁止su - root切换root 2. 禁止root远程登录2.1 ssh禁止root登录2.2 禁止远程桌面登录 本文主要介绍&#xff1a; 如何禁止普通用户切换到r…