当前位置: 首页 > news >正文

C++ --> 类和对象(二)

前言

在前面简单的介绍了OOP,什么是类,在类中的this指针。接下来就深入理解类和对象。

默认成员函数

  • 默认构造函数:用于在创建对象时初始化对象的成员变量。
  • 默认拷贝构造函数:用于使用已存在的对象来初始化新创建的对象。
  • 默认析构函数:在对象生命周期结束时执行清理操作,通常是删除动态分配的资源。
  • 默认重载赋值运算符:用于将一个对象的值赋给另一个已存在的对象。
  • 默认移动构造函数(C++11及以后版本):用于将资源从一个对象转移到另一个对象,而不是复制这些资源。
  • 默认重载移动赋值操作符(C++11及以后版本):用于将一个对象的资源移动到另一个已存在的对象

接下来就依次介绍默认成员函数

一、构造函数

构造函数的特性

构造函数类似于初始化函数,在写Stack时候,首先需要初始化Stack。

构造函数并不是开辟空间创建对象,而是初始化

  1. 函数名与类名相同
  2. 无返回值
  3. 对象实例化时编译器自动调用构造函数
  4. 构造函数可以重载
class Date
{
public://构造函数Date()								//无参构造函数{}Date(int year , int month , int day )  //带参构造函数{_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{Date d0;//调用无参数构造 初始化的值是随机值Date d1(2024, 7.1, 8);//调用带参构造d1.Print();return 0;
}

注意:在调用无参构造函数,初始化时候是随机值。

  1. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦 用户显式定义编译器将不再生成。
class Date
{
public://Date(int year, int month, int day)//{//	_year = year;//	_month = month;//	_day = day;//}
private:int _year;int _month;int _day;
};int main()
{Date d0;Date d1;d1.Print();return 0;
}
  1. 在这段代码中,没有显示定义构造函数,那么编译器就会生成一个默认构造函数.
  2. 如果显示定义(即将代码取消注释),那么 d0 d1将没有可调用的默认构造函数 .

注意:在 (C++11) 中,针对内置类型不初始化打了补丁,成员变量在声明的时候可以给默认值

class Date
{
private:int _year = 1;int _month = 1;int _day = 1;
};
  1. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。

    注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为 是默认构造函数

//无参构造函数
Date(int year, int month, int day)
{_year = year;_month = month;_day = day;
}
//全缺省构造函数
Date(int year = 1, int month = 1, int day = 1)
{_year = year;_month = month;_day = day;
}

小结

  • 一般情况下,构造函数自己写
  • 内置类型都有缺省值,并且符合我们的要求可以不写构造函数
  • 类成员变量均为自定义类型(这些均有自己的构造函数),会调用他们自己的构造函数.

二、析构函数

析构函数的特性

  1. 析构函数名是类名前面加“~”
  2. 无返回值
  3. 在一个类中,如析构函数未显示定义,将自动生成.
  4. 不可以重载
  5. 对象生命周期结束时候C++编译系统自动调用析构函数
//在这里面以以  Stack  为例
class Stack
{~Stack(){free(_a);_a = nullptr;}
private:int* _a;int _capacity;int _size;
};
  1. 如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如 Date类;有资源申请时,一定要写,否则会造成资源泄漏,比如Stack类。

小结

  • 内置类型不做任何处理,调用其自己的析构函数.
  • 动态申请资源,就要显示定义析构函数.
  • 没有动态申请资源可以不写析构函数.

三、拷贝构造函数

拷贝构造函数的特性

  1. 只有单个形参数,一般用const修饰.
    • const修饰是为了防止赋值错误:例如:本应该_year = year 却写成了year = _year;
  2. 拷贝构造是析构函数的重载形式.
  3. 参数只有一个,且是类类型对象的引用
  4. 自定义传值调用C++编译器调用其拷贝构造函数.
  5. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错, 因为会引发无穷递归调用
class Date
{
public:Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// DateP(const Date d); 错误示范Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}
private:int _year;int _month;int _day;
};int main()
{Date d1(2024,7,9);Date d2(d1);return 0;
}

注意 : 如果拷贝构造函数不加引用,会发生无穷递归. 函数在传值调用会调用拷贝构造函数,如其函数不加入引用(即传值调用),就会发生无限递归.

  1. 若未显示定义拷贝构造函数,编译器自动生成.
  • 内置类型完成值拷贝(浅拷贝)
  • 自定义类型会调用它自己的拷贝构造。

深浅拷贝

浅拷贝:浅拷贝是指复制对象时只复制其基本数据类型成员和指针成员,而不复制指针所指向的内存内容

深拷贝:深拷贝则是在复制对象时,不仅复制基本数据类型成员和指针成员,还会为指针所指向的内存内容分配新的内存空间,并将原有内容复制过去。

四、赋值运算符重载(关键字:operator)

运算符重载

运算符重载的概念

  • 运算符重载是一项允许开发者为用户自定义的数据类型(如类)定义运算符的特性。
  • 通过运算符重载,可以使自定义类型的对象能够使用类似于内置类型的运算符进行操作,从而提高代码的可读性和自然性。
  • 运算符重载实质上是函数重载的一种特殊形式,重载的函数通过关键字 operator 后跟要重载的运算符符号来命名。

运算符重载的规则

  • 运算符重载的限制:C++不允许创建新的运算符,只能对已存在的运算符进行重载。重载运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个数及语法结构。
  • 运算符重载的实现方式:运算符重载可以通过类的成员函数或非成员函数(通常作为友元函数)来实现。成员函数形式的运算符重载通常用于双目运算符,因为它们可以省略一个参数(即隐含的 this 指针)。非成员函数形式的运算符重载则适用于不涉及类对象或需要对称操作的场合。
  • 运算符重载的设计原则:重载运算符应该保持其操作的直觉性,避免产生歧义。例如,重载加号运算符(+)应该执行加法操作,而不是其他操作。

注意:

  1. 作为类成员函数重载,其形参操作数少一个,形参的第一个参数隐含的this指针。
  2. .*)(: :)(sizeof)(? : :)(.)这五种不可以重载。

赋值运算符重载

重载格式:
  • 参数类型:const T&,传递引用可以提高传参效率
  • 返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值 检测是否自己给自己赋值
  • 返回*this :要复合连续赋值的含义
重载注意:
  • 赋值运算符重载不能是全局函数,它必须是类的成员函数。
  • 重载赋值运算符时,应当考虑异常安全性,确保即使在赋值过程中发生异常,也不会留下半更新的状态。
  • 重载赋值运算符时,可以选择返回const引用,以避免在赋值后对当前对象进行不必要的修改。
class Date
{ 
public :Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}Date (const Date& d){_year = d._year;_month = d._month;_day = d._day;}//赋值运算符重载   Date& operator=(const Date& d)//返回this,用来连续赋值。{if(this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}
private:int _year ;int _month ;int _day ;
};
  • 赋值运算符只能重载成类的成员函数不能重载成全局函数(因为其属于默认成员函数

赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现 一个全局的赋值运算符重载,就 和编译器在类中生成的默认赋值运算符重载冲突了,故赋值 运算符重载只能是类的成员函数。

  • 用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。(浅拷贝)

单目运算符号(自增、自减)

自增

在下面的例子中:

前置:

  • 前置++:返回+1之后的结果
  • 注意:this指向的对象函数结束后不会销毁,故以引用方式返回提高效率

后置:

  • 前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确重载
  • C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器 自动传递
  • 注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存 一份,然后给this+1
  • temp是临时对象,因此只能以值的方式返回,不能返回引用
// 前置++
Date& Date::operator++()
{return *this += 1;
}
// 后置++
Date Date::operator++(int)
{Date tmp;	tmp += 1;return *this;
}

自减

在这里和前置++ 后置++ 思想一致。

// 后置--
Date Date::operator--(int)
{Date tmp;tmp -= 1;return *this;
}
// 前置--
Date& Date:: operator--()
{return *this -= 1;
}

相关文章:

C++ --> 类和对象(二)

前言 在前面简单的介绍了OOP&#xff0c;什么是类&#xff0c;在类中的this指针。接下来就深入理解类和对象。 默认成员函数 默认构造函数&#xff1a;用于在创建对象时初始化对象的成员变量。默认拷贝构造函数&#xff1a;用于使用已存在的对象来初始化新创建的对象。默认析构…...

利用宝塔安装一套linux开发环境

更新yum&#xff0c;并且更换阿里镜像源 删除yum文件 cd /etc/yum.repos.d/ 进入yum核心目录 ls sun.repo rm -rf * 删除之前配置的本地源 ls 配置阿里镜像源 wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo 配置扩展包 wge…...

VB 实例:掌握 Visual Basic 编程的精髓

VB 实例:掌握 Visual Basic 编程的精髓 引言 Visual Basic(简称VB)是一种由微软开发的高级编程语言,它结合了易于使用的界面和强大的编程功能,使得初学者和专业人士都能快速开发Windows桌面应用程序。本文将通过一系列实例,深入探讨VB编程的基础知识和高级技巧,帮助读…...

层次分析法:matlab代码实现

计算权重&#xff1a; 一、算术平均法 关于矩阵&#xff1a; 1、矩阵的输入写法 [ ; ; ]同行用空格或逗号隔开&#xff0c;不同行用分号间隔 2、矩阵求和 默认按列求和 asum(E) 等同于 asum(E,1) 得到行向量 按行求和 asum(E,2) 得到列向量 对整个矩阵求和 asum(E,"all&…...

07-7.5.3 处理冲突的方法

&#x1f44b; Hi, I’m Beast Cheng &#x1f440; I’m interested in photography, hiking, landscape… &#x1f331; I’m currently learning python, javascript, kotlin… &#x1f4eb; How to reach me --> 458290771qq.com 喜欢《数据结构》部分笔记的小伙伴可以…...

几何距离与函数距离:解锁数据空间中的奥秘

几何距离&#xff1a;直观的空间度量 几何距离&#xff0c;顾名思义&#xff0c;是我们在几何学中熟悉的距离概念&#xff0c;如欧几里得距离、曼哈顿距离和切比雪夫距离等。这些距离度量直接反映了数据点在多维空间中的位置关系。 欧几里得距离&#xff1a;最为人熟知的几何距…...

LabVIEW的Actor Framework (AF) 结构介绍

LabVIEW的Actor Framework (AF) 是一种高级架构&#xff0c;用于开发并发、可扩展和模块化的应用程序。通过面向对象编程&#xff08;OOP&#xff09;和消息传递机制&#xff0c;AF结构实现了高效的任务管理和数据处理。其主要特点包括并发执行、动态可扩展性和强大的错误处理能…...

gitlab 搭建使用

1. 硬件要求 ##CPU 4 核心500用户 8 核心1000用户 ##内存 4 G内存500用户 8 G内存1000用户 2. 下载 链接 3. 安装依赖 yum -y install curl openssh-server postfix wget 4. 安装gitlab组件 yum -y localinstall gitlab-ce-15.9.3-ce.0.el7.x86_64.rpm 5. 修改配置文…...

探索JT808协议在车辆远程视频监控系统中的应用

一、部标JT808协议概述 随着物联网技术的迅猛发展&#xff0c;智能交通系统&#xff08;ITS&#xff09;已成为现代交通领域的重要组成部分。其中&#xff0c;车辆远程监控与管理技术作为ITS的核心技术之一&#xff0c;对于提升交通管理效率、保障道路安全具有重要意义。 JT8…...

视频使用操作说明书-T80005系列视频编码器如何对接海康NVR硬盘录像机,包括T80005系列高清HDMI编码器、4K超高清HDMI编码器

视频使用操作说明书-T80005系列视频编码器如何对接海康NVR硬盘录像机&#xff0c;包括T80005系列高清HDMI编码器、4K超高清HDMI编码器。 视频使用操作说明书-T80005系列视频编码器如何对接海康NVR硬盘录像机&#xff0c;包括T80005系列高清HDMI编码器、4K超高清HDMI编码器 同三…...

keep-alive缓存组件

keep-alive缓存组件是Vue.js中的一个特殊组件&#xff0c;主要用于缓存内部组件的数据状态&#xff0c;以提高应用的性能和用户体验。以下是关于keep-alive缓存组件的详细解析&#xff1a; 一、作用 缓存组件状态&#xff1a;当组件在<keep-alive>内部切换时&#xff0…...

Linux上如何安装ffmpeg视频处理软件

在Linux上安装ffmpeg需要以下步骤&#xff1a; 更新系统 在开始安装之前&#xff0c;首先需要更新系统以获取最新的软件包列表和版本。在终端中执行以下命令&#xff1a; sudo apt update sudo apt upgrade安装依赖库 ffmpeg依赖于一些库和工具&#xff0c;需要先安装它们。在…...

element如何实现自定义表头?

有时候我们需要实现自定义表头,例如表头里加按钮啥的,这时候就需要用到自定义表头,但是官方对自定义表头的使用写的还是比较简单,今天就来详细说说 在需要使用自定义表头的表头上使用:render-header来启用自定义表头: <el-table-column :render-header="button&…...

OTP防重放攻击

OTP本意是一次性口令&#xff0c;比如邮箱验证码&#xff0c;短信验证码&#xff0c;或者根据totp或者hotp生成的默认30秒一变的6位数字。 不过开发者要注意&#xff0c;必须要在验证成功后失效那个验证码&#xff0c;不然就会导致重放攻击。 对于邮箱验证码&#xff0c;服务器…...

Oracle数据库加密与安全

Wallet简介&#xff1a; Oracle Wallet(即内部加密技术TDE( Transparent DataEncryption&#xff09; TDE是 Oracle10gR2中推出的一个新功能,使用时要保证Oracle版本是在10gR2或者以上 Wallet配置&#xff1a; 1.创建一个新目录&#xff0c;并指定为Wallet目录 /home/oracle…...

【YOLO格式的数据标签,目标检测】

标签为 YOLO 格式&#xff0c;每幅图像一个 *.txt 文件&#xff08;如果图像中没有对象&#xff0c;则不需要 *.txt 文件&#xff09;。*.txt 文件规格如下: 每个对象一行 每一行都是 class x_center y_center width height 格式。 边框坐标必须是 归一化的 xywh 格式&#x…...

Memcached内存碎片清理术:优化缓存性能的策略

标题&#xff1a;Memcached内存碎片清理术&#xff1a;优化缓存性能的策略 内存碎片是Memcached在长期运行过程中常见的问题&#xff0c;它会降低缓存效率并影响性能。作为高效的分布式内存缓存系统&#xff0c;Memcached提供了多种内存碎片整理策略。本文将详细介绍这些策略&…...

禁止使用存储过程

优质博文&#xff1a;IT-BLOG-CN 灵感来源 什么是存储过程 存储过程Stored Procedure是指为了完成特定功能的SQL语句集&#xff0c;经编译后存储在数据库中&#xff0c;用户可通过指定存储过程的名字并给定参数&#xff08;如果该存储过程带有参数&#xff09;来调用执行。 …...

Flink异常:org/apache/hadoop/hive/ql/parse/SemanticException

在flink项目中跑 上面这段代码出现如下这个异常&#xff0c; java.lang.NoClassDefFoundError: org/apache/thrift/TException 加上下面这个依赖后不报错 <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId…...

Java:构造函数与对象

第一章&#xff1a;构造函数揭秘 —— 创造者的第一次触碰 构造函数&#xff0c;顾名思义&#xff0c;是用于创建和初始化对象的特殊方法。它没有返回类型&#xff0c;名字与类名一致。构造函数是对象诞生的第一步&#xff0c;也是最至关重要的一步。让我们通过一个生动的例子…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...