c++类和对象(2)

1. 类的6个默认成员函数

在C++中,如果一个类没有显式定义某些成员函数,编译器会默认为这个类生成六个默认成员函数。以下是这六个默认成员函数:

默认构造函数(Default Constructor)

如果类没有定义任何构造函数,编译器会提供一个默认构造函数,这个默认构造函数是一个无参构造函数,它的作用是创建一个对象,并为对象的成员变量提供默认值。

析构函数(Destructor)

如果类没有定义析构函数,编译器会提供一个默认的析构函数,默认析构函数是一个空函数体,用于在对象生命周期结束时释放资源。

拷贝构造函数(Copy Constructor)

用于通过一个同类型的已存在对象来初始化一个正在创建的对象。默认的拷贝构造函数执行成员的逐位复制。

拷贝赋值运算符(Copy Assignment Operator)

用于将一个对象赋值给同类型的另一个已存在对象。默认的拷贝赋值运算符执行成员的逐位赋值。

移动构造函数(Move Constructor) (C++11及以后)

当需要通过一个临时对象来初始化同类型的另一个对象时,移动构造函数会被调用。默认的移动构造函数“窃取”临时对象的资源。

移动赋值运算符(Move Assignment Operator) (C++11及以后)

用于将一个临时对象赋值给同类型的另一个已存在对象。默认的移动赋值运算符也是“窃取”临时对象的资源。

2. 构造函数

构造函数是类的一个特殊成员函数,它的主要作用是在创建类的对象时初始化对象的成员变量。构造函数具有以下特点:

  1. 函数名称:构造函数的名称必须与类名相同。
  2. 参数:构造函数可以没有参数,也可以有多个参数,用于提供初始化成员变量的值。
  3. 返回类型:构造函数没有返回类型,即使是void也不可以。
  4. 作用:在对象创建时自动调用,用于初始化对象的成员变量。

默认构造函数

如果类没有定义任何构造函数,编译器会提供一个默认构造函数。如果定义了其他构造函数,但仍然需要一个无参的构造函数,则必须显式定义默认构造函数。

class MyClass {
public:MyClass() {// 默认构造函数的实现}
};

 参数化构造函数

允许在创建对象时传递参数,以初始化对象的成员变量。

class MyClass {
public:int x;MyClass(int val) : x(val) {// 参数化构造函数的实现}
};

 转换构造函数

允许通过一个不同类型的值来创建对象。

class MyClass {
public:MyClass(int val) {// 转换构造函数的实现}
};

 初始化列表

构造函数可以使用初始化列表来初始化成员变量,这通常比在函数体内赋值更高效。

class MyClass {
public:int x;MyClass() : x(10) {// 使用初始化列表}
};

3. 析构函数

析构函数是类的一个特殊成员函数,它的作用是在对象生命周期结束时执行必要的清理工作。析构函数具有以下特点:

  1. 函数名称:析构函数的名称是在类名前加上波浪号(~)。
  2. 参数:析构函数没有参数,因此不能被重载。
  3. 返回类型:析构函数没有返回类型,即使是void也不可以。
  4. 作用:在对象被销毁时自动调用,用于释放对象所占用的资源,如动态分配的内存、打开的文件句柄、网络连接等。

规则

  • 每个类只能有一个析构函数。
  • 如果类没有显式定义析构函数,编译器会自动生成一个默认的析构函数,该默认析构函数是一个空函数体。
  • 如果类中包含指向动态分配内存的指针成员,则通常需要定义一个自定义的析构函数来释放这些内存。
class MyClass {
public:MyClass() {// 构造函数的实现,可能包含动态内存分配}~MyClass() {// 析构函数的实现,释放动态分配的内存}
private:int* data; // 指向动态分配内存的指针
};int main() {MyClass obj; // 创建对象,调用构造函数// ... 使用对象 ...return 0; // 程序结束,obj对象生命周期结束,调用析构函数
}

4. 拷贝构造函数

拷贝构造函数是一种特殊的构造函数,它用于创建一个新对象作为另一个同类对象的副本。拷贝构造函数具有以下特点:

  1. 函数名称:拷贝构造函数的名称与类名相同,且有一个参数,该参数是对类类型对象的引用。
  2. 参数:拷贝构造函数的参数必须是类类型的引用,通常使用常量引用,以避免修改原对象,并允许传递临时对象。
  3. 返回类型:拷贝构造函数没有返回类型,即使是void也不可以。
  4. 作用:当需要通过已存在的对象来初始化一个新对象时,拷贝构造函数会被调用。
class MyClass {
public:MyClass(const MyClass& other) {// 拷贝构造函数的实现// 通常用于复制成员变量}// 其他成员函数和成员变量...
};

默认拷贝构造函数

如果类没有显式定义拷贝构造函数,编译器会自动生成一个默认的拷贝构造函数。默认拷贝构造函数执行成员的逐位复制(浅拷贝)。对于包含指针成员的类,默认拷贝构造函数可能会导致问题,因为它只会复制指针的值,而不是指针指向的数据。

自定义拷贝构造函数

在某些情况下,需要自定义拷贝构造函数来执行深拷贝,以确保每个对象都有自己独立的副本。

class MyClass {
public:int* data;MyClass(int value) : data(new int(value)) {}// 自定义拷贝构造函数MyClass(const MyClass& other) : data(new int(*other.data)) {// 执行深拷贝}~MyClass() {delete data; // 释放动态分配的内存}
};

5. 赋值运算符重载

在C++中,赋值运算符 = 可以被重载以定制对象之间的赋值行为。当你定义了一个类,并且希望对象能够使用 = 运算符进行赋值时,你可能需要重载赋值运算符。

  1. 参数类型:赋值运算符重载函数应该有一个参数,该参数是类类型的引用。通常使用常量引用,以允许传递临时对象,并防止在赋值过程中修改右操作数。

  2. 返回类型:赋值运算符重载函数应该返回一个指向当前对象的引用,通常是一个 *this 指针。

  3. 函数名称:赋值运算符重载的函数名是 operator=

  4. 成员函数:赋值运算符必须是类的成员函数。

class MyClass {
public:int* data;MyClass(int value) : data(new int(value)) {}// 赋值运算符重载MyClass& operator=(const MyClass& other) {if (this != &other) { // 避免自我赋值delete data;      // 删除旧值data = new int(*other.data); // 深拷贝}return *this; // 返回当前对象的引用}~MyClass() {delete data; // 析构函数中释放动态分配的内存}
};

 

注意事项:

  • 自我赋值检查:在赋值运算符的实现中,检查自我赋值是非常重要的,以避免在释放内存后使用悬空指针。
  • 资源管理:如果类管理动态分配的资源,赋值运算符应该正确地管理这些资源,避免内存泄漏和悬挂指针。
  • 返回值:赋值运算符应该返回当前对象的引用,这允许链式赋值,例如 a = b = c;

6. const成员函数

在C++中,const成员函数是指那些承诺不修改调用对象的数据成员的函数。当你声明一个成员函数为const时,你告诉编译器这个函数不会改变对象的任何成员变量(非静态成员变量)。这是通过在函数声明和定义后面加上const关键字来实现的。

class MyClass {
public:void normalFunction() {// 可以修改成员变量}void constFunction() const {// 不能修改成员变量}
};

 

注意事项

  • const成员函数内部,你不能修改任何非静态成员变量。
  • 你可以修改静态成员变量和局部变量,因为这些变量不与对象的状态直接相关。
  • 你可以在const成员函数内部调用其他非const成员函数,但前提是这些函数不修改任何非静态成员变量。

7. 取地址及const取地址操作符重载

在C++中,你可以重载几种特殊的成员操作符,包括取地址操作符 & 和 const 取地址操作符 const &。虽然这些操作符通常不需要重载,因为编译器默认提供的版本就已经足够使用,但在某些特殊情况下,你可能需要自定义它们的行为。

重载取地址操作符 &

class MyClass {
public:// 重载取地址操作符MyClass* operator&() {// 返回当前对象的地址return this;}
};

重载const取地址操作符 const &

class MyClass {
public:// 重载const取地址操作符const MyClass* operator&() const {// 返回当前对象的const地址return this;}
};

注意事项

  • 重载取地址操作符通常不是一个好主意,因为这可能会导致混淆和意外的行为。通常,编译器提供的默认行为是正确的,即返回对象的实际地址。
  • 如果你确实重载了这些操作符,它们必须返回指向类类型的指针。对于 const 版本,返回类型应该是指向 const 类型的指针。
  • 重载这些操作符的返回类型不能是引用类型,因为地址操作符的预期行为是返回一个指针。
  • 重载这些操作符的目的是为了改变它们的行为,但通常不建议这样做,除非你有非常特殊的需求。

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

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

相关文章

单片机学习笔记 15. 串口通信(理论)

更多单片机学习笔记:单片机学习笔记 1. 点亮一个LED灯单片机学习笔记 2. LED灯闪烁单片机学习笔记 3. LED灯流水灯单片机学习笔记 4. 蜂鸣器滴~滴~滴~单片机学习笔记 5. 数码管静态显示单片机学习笔记 6. 数码管动态显示单片机学习笔记 7. 独立键盘单片机学习笔记 8…

树莓派5+文心一言 -> 智能音箱

一、简介 效果:运行起来后,可以连续对话 硬件:树莓派5、麦克风、音箱,成本500-1000 软件:snowboy作为唤醒词、百度语音作为语音识别、brain作为指令匹配、百度文心一言作为对话模块、微软的edge-tts语音合成... 二…

SAP SD学习笔记17 - 投诉处理3 - Credit/Debit Memo依赖,Credit/Debit Memo

上一章讲了 请求书(发票)的取消。 SAP SD学习笔记16 - 请求书的取消 - VF11-CSDN博客 再往上几章,讲了下图里面的返品传票: SAP SD学习笔记14 - 投诉处理1 - 返品处理(退货处理)的流程以及系统实操&#…

Linux服务器使用JupyterLab

一、JupyterLab的配置 1. conda配置 自行搜索conda安装与配置。 2. 环境创建 (1)创建环境 conda create -n jupyter python3.10(2)激活环境 conda activate jupyter(3)安装jupyter包 pip install -i…

Flutter:页面滚动

1、单一页面,没有列表没分页的,推荐使用:SingleChildScrollView() return Scaffold(backgroundColor: Color(0xffF6F6F6),body: SingleChildScrollView(child: _buildView()) );2、列表没分页,如购物车页,每个item之间…

使用GitZip for github插件下载git仓库中的单个文件

背景:git仓库不知道抽什么疯,下载不了单个文件,点击下载没有反应,遂找寻其他方法,在这里简单记录下。 使用GitZip for github插件下载仓库中的单个文件 1、首先在浏览器安装插件,并确保为打开状态。 2、然…

Unet改进57:在不同位置添加SFHF

本文内容:在不同位置添加CBAM注意力机制 论文简介 由于恶劣的大气条件或独特的降解机制,自然图像会遭受各种退化现象。这种多样性使得为各种恢复任务设计一个通用框架具有挑战性。现有的图像恢复方法没有探索不同退化现象之间的共性,而是侧重于在有限的恢复先验下对网络结构…

数据结构(初阶7)---七大排序法(堆排序,快速排序,归并排序,希尔排序,冒泡排序,选择排序,插入排序)(详解)

排序 1.插入排序2.希尔排序3.冒泡排序4.选择排序(双头排序优化版)5.堆排序6.快速排序1). 双指针法2).前后指针法3).非递归法 7.归并排序1).递归版本(递归的回退就是归并)2).非递归版本(迭代版本) 计算机执行的最多的操作之一就有排序,排序是一项极其重要的技能 接下…

DataWhale—PumpkinBook(TASK07支持向量机)

课程开源地址及相关视频链接:(当然这里也希望大家支持一下正版西瓜书和南瓜书图书,支持文睿、秦州等等致力于开源生态建设的大佬✿✿ヽ(▽)ノ✿) Datawhale-学用 AI,从此开始 【吃瓜教程】《机器学习公式详解》(南瓜…

【Python数据分析五十个小案例】使用自然语言处理(NLP)技术分析 Twitter 情感

博客主页:小馒头学python 本文专栏: Python爬虫五十个小案例 专栏简介:分享五十个Python爬虫小案例 项目简介 什么是情感分析 情感分析(Sentiment Analysis)是文本分析的一部分,旨在识别文本中传递的情感信息&…

【数据结构与算法】排序算法(上)——插入排序与选择排序

文章目录 一、常见的排序算法二、插入排序2.1、直接插入排序2.2、希尔排序( 缩小增量排序 ) 三、选择排序3.1、直接选择排序3.2、堆排序3.2.1、堆排序的代码实现 一、常见的排序算法 常见排序算法中有四大排序算法,第一是插入排序,二是选择排序&#xff…

Educator头歌:离散数学 - 图论

第1关&#xff1a;图的概念 任务描述 本关任务&#xff1a;学习图的基本概念&#xff0c;完成相关练习。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;图的概念。 图的概念 1.一个图G是一个有序三元组G<V,R,ϕ>&#xff0c;其中V是非空顶点集合&am…

oracle RAC各版本集群总结和常用命令汇总

oracle RAC学习 RAC介绍 RAC&#xff1a;高可用集群&#xff0c;负载均衡集群&#xff0c;高性能计算集群 RAC是⼀种⾼可⽤&#xff0c;⾼性能&#xff0c;负载均衡的share-everything的集群 8i:内存融合雏形 内存融合雏形&#xff08;Oracle Parallel Server&#xff09;…

数据资产管理是什么?为什么重要?核心组成部分(分类分级、登记追踪、质量管理、安全合规)、实施方法、未来趋势、战略意义

文章目录 一、引言&#xff1a;数据的新时代二、什么是数据资产管理&#xff1f;2.1 定义2.2 核心功能 三、为什么数据资产管理至关重要&#xff1f;3.1 面对的数据管理挑战 四、数据资产管理的核心组成部分4.1 数据分类与分级4.2 数据资产登记与追踪4.3 数据质量管理4.4 数据安…

C++高阶算法[汇总]

&#xff08;一&#xff09;高精度算法概述 高精度算法是指能够处理超出常规数据类型表示范围的数值的算法。在 C 中&#xff0c;标准数据类型通常有固定的位数和精度限制&#xff0c;而高精度算法可以解决大数运算、金融计算和科学计算等领域的问题。 &#xff08;二&#x…

springboot365高校疫情防控web系统(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;高校疫情防控的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为…

Electron实现打开子窗口加载vue路由指定的组件页面白屏

白屏有两种情况&#xff1a; Vue项目使用的history路由的话就会显示空白&#xff0c;加载不出来路由&#xff0c;也不能跳转路由 这种情况看我上一篇文章Electron vue3 打包之后不能跳转路由-CSDN博客 Electron中已经能正常加载页面跳转路由&#xff0c;但是创建子窗口加载子页…

智能探针技术:实现可视、可知、可诊的主动网络运维策略

网络维护的重要性 网络运维是确保网络系统稳定、高效、安全运行的关键活动。在当今这个高度依赖信息技术的时代&#xff0c;网络运维的重要性不仅体现在技术层面&#xff0c;更关乎到企业运营的方方面面。网络运维具有保障网络的稳定性、提升网络运维性能、降低企业运营成本等…

泷羽sec-shell脚本(全) 学习笔记

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…

鸿蒙学习使用模拟器运行应用(开发篇)

文章目录 1、系统类型和运行环境要求2、创建模拟器3、启动和关闭模拟器4、安装应用程序包和上传文件QA:在Windows电脑上启动模拟器&#xff0c;提示未开启Hyper-V 1、系统类型和运行环境要求 Windows 10 企业版、专业版或教育版及以上&#xff0c;且操作系统版本不低于10.0.18…