C++初阶篇----类与对象中卷

目录

  • 引言
  • 1. 构造函数
    • 1.1概念
    • 1.2 特性
  • 2. 析构函数
    • 2.1 概念
    • 2.2 特性
  • 3. 拷贝构造函数
    • 3.1 概念
    • 3.2特征
  • 4. 赋值运算符重载
    • 4.1 运算符重载
    • 4.2 赋值运算符重载
    • 4.3 前置++和后置++重载
  • 5.日期类的实现
  • 6.const成员
  • 7.取地址及const取地址操作符重载

引言

当一个类既没有成员变量又没有成员函数时(也就是空类,没有成员),编译器又该如何面对?
此时的编译器会无动于衷?非也

编译器会自动生成6个默认成员函数:
用户没有显示实现,编译器会生成的成员函数成为默认成员函数
在这里插入图片描述

1. 构造函数

1.1概念

构造函数用于在创建对象时初始化对象的状态。构造函数的名称与类名相同,不返回任何值(包括void),因此它们没有返回类型。

构造函数在以下情况下被调用:

  1. 当创建对象时,编译器会自动调用该对象的构造函数来初始化对象。
  2. 在使用new关键字动态分配内存时,构造函数也会被调用。
  3. 当对象作为函数参数传递给函数时,如果需要,构造函数也会被调用。

如下,构造函数的调用与创建

class Date
{
public://void Init(int year=2025, int month=2, int day=26)void Init(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 s;s.Init(2024,2,26);//s.Init();s.Print();return 0;
}

构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证
每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。

1.2 特性

构造函数的职责是初始化对象,而非开设空间来创建对象
特性:

  1. 函数名与类名一样
  2. 无返回值
  3. 对象实例化,自动调用对用的构造函数
  4. 构造函数可以重载
int main()
{Date s;     // 若没有写构造函数,自动调用无参构造函数//s.Init(2024,2,26);s.Init();//s.Init;     错误的s.Print();return 0;
}
  1. 若类中并没有定义构造函数,那么编译器会自动生成一个**无参**的默认构造函数,当用户显示定义那么就不会自动生成

注意:那么自动生成的构造函数的作用是什么?
通过实验可以得出,当没有定义构造函数而创建对象,而自动调用构造函数,最后却和没有初始化的效果一样(自动调用后值为随机值)
C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类
型,如:int/char…,自定义类型就是我们使用class/struct/union等自己定义的类型
如下,自动调用自定义类型的构造函数的作用

#include"iostream"
using namespace std;
class little
{
public:little(){cout << "little" << endl;_mount = 24;cout << _mount << endl;}private:int _mount = 80;
};class Date
{
public:void Print(){cout << _year << _month << _day << endl;}
private://内置类型int _year;int _month;int _day;//自定义类型little t;
};int main()
{Date s;s.Print();return 0;
}

在这里插入图片描述

  1. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
    注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为
    是默认构造函数。

2. 析构函数

2.1 概念

析构函数的概念:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。
在对象销毁时自动被调用,用于清理对象所占用的资源、释放内存等操作。它的名称与类名相同,前面加上波浪号(~),不接受任何参数,也没有返回值(包括void)。

2.2 特性

  1. 定义析构函数时,是在类名前加上 " ~ "
  2. 无参数无返回类型
  3. 一个类只能有一个析构函数,若为显式定义,系统会自动生成默认的析构函数.(析构函数无法重载)
  4. 对象生命周期结束时,C++编译系统自动调用析构函数
//Date函数
class Date
{
public:void Init(int year=2025, int month=2, int day=26){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day<< endl;}~Date(){cout << "~Date()" << endl;}private:int _year;int _month;int _day;
};int main()
{Date s;//s.Init(2024,2,26);s.Init();//s.Init;     错误的s.Print();return 0;
}

在这里插入图片描述

注意:关于编译器自动生成的析构函数,与构造函数的原理类似
原理便是嵌套类的自调用

include"iostream"
using namespace std;
class little
{
public:little(){cout << "little" << endl;_mount = 24;cout << _mount << endl;}~little(){cout << "~littel()" << endl;}private:int _mount = 80;
};class Date
{
private://内置类型int _year;int _month;int _day;//自定义类型little t;
};int main()
{Date s;return 0;
}

在这里插入图片描述
类中若没有开辟空间,可以不写析构函数,相当于C语言中的临时变量,出了生命域便销毁了,但若有资源申请,一定要写析构函数的,就好比C中开辟了空间最后要主动释放空间.

3. 拷贝构造函数

3.1 概念

只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰)
用于创建一个新对象并初始化为同一类的现有对象的副本。它的作用是用一个已存在的对象来初始化一个新创建的对象。

常用情况:

  1. 将一个对象作为参数传递给函数,以值传递的方式,或者以按值返回的方式。
  2. 在函数中创建一个新对象,并将其初始化为另一个对象的副本。
  3. 当对象被复制给另一个对象时,如对象的赋值操作或对象的初始化。

3.2特征

特殊成员函数之一

  1. 拷贝构造函数是构造函数的一个重载形式
  2. 参数只有一个且必须是"类"类型对象的**引用**,(注意:使用传值方式编译器直接报错,因为在传值过去,会自动触发调用函数,而进入无穷递归)

class Date
{
public://Date(const Date d )  错误的写法Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}Date(int year=2025, int month=2, int day=26){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day<< endl;}~Date(){cout << "~Date()" << endl;}private:int _year;int _month;int _day;
};int main()
{Date s(2024,2,27);Date m(s);s.Print();m.Print();return 0;
}

在这里插入图片描述
若以传值方式,造成无穷递归:
在这里插入图片描述

  1. 若未显式定义,编译器会生成默认的拷贝构造函数。默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。如:类中成员需要开辟空间,此时生成的拷贝构造函数会拷贝这片空间,而不是开辟空间.

注意:在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的
注意:类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请时,则拷贝构造函数是一定要写的,否则就是浅拷贝。

4. 赋值运算符重载

4.1 运算符重载

运算符重载是具有特殊函数名的函数
运算符重载的语法:

return_typefed operator symbol(parameter list)
{
//操作实现
}
class Date
{
public:Date(int year=2025, int month=2, int day=26){_year = year;_month = month;_day = day;}bool operator==(const Date& d){return _year == d._year &&_month == d._month &&_day == d._day;}~Date(){cout << "~Date()" << endl;}private:int _year;int _month;int _day;
};
int main()
{Date d;Date s(2025, 2, 26);cout << (s == d) << endl;return 0;
}

在这里插入图片描述

运算符重载的一些注意事项:

 1. 不能创建新的运算符,只能重载已有的运算符。2.  不能改变运算符的优先级和结合性。3.  一些运算符(如.和::)无法被重载。4.  不能重载的运算符包括:.(成员访问运算符)、.*(成员指针访问运算符)、::(作用域解析运算符)、?:(条件运算符)、sizeof(大小运算符)、typeid(类型信息运算符)等。

4.2 赋值运算符重载

1.赋值运算符重载格式:

  1. 参数类型:const T&,传递引用提高效率
  2. 返回值类型:T&,返回引用可以提高返回得效率
  3. 检测是否自己 给自己赋值
  4. 返回*this:复合连续赋值的含义
class Date
{
public://Date(const Date d )  错误的写法Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}Date(int year=2025, int month=2, int day=26){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day<< endl;}Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;  //解引用}~Date(){cout << "~Date()" << endl;}private:int _year;int _month;int _day;
};
int main()
{Date d(2024, 2, 27);Date s = d;s.Print();d.Print();return 0;
}

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

4.3 前置++和后置++重载

class Date{
public:
//前置++:先加1再返回
// 注意:this指向的对象函数结束后不会销毁,故以引用方式返回提高效率
Date& operator++()
{_day += 1;return *this;
}//后置++:先返回再加1
//C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器
//自动传递
//由于temp为临时对象,故不用引用
Date operator++(int)
{Date temp(*this);_day += 1;return temp;
}private://…………}

5.日期类的实现

日期类函数实现

6.const成员

将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。
在这里插入图片描述

class Date
{
public:Date(int year=2025, int month=2, int day=26){_year = year;_month = month;_day = day;}void Print()const{cout << "Print()const" << endl;cout << _year << "-" << _month << "-" << _day<< endl;}void Print(){cout << _year << "-" << _month << "-" << _day<< endl;}~Date(){cout << "~Date()" << endl;}private:int _year;int _month;int _day;
};
int main()
{Date d(2024,2,27);d.Print();const Date s(2024, 2, 27);s.Print();return 0;
}

在这里插入图片描述

注意: const Date 变量时,不能去调用非const的成员函数,而 Date 变量可以去调用const 的成员函数

原理是:加上const 变量的权限被缩小,权限小的无法访问更高级权限的成员函数,而没有const的变量,去访问有const的成员函数,是高权限访问低权限

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

这两个默认成员函数一般不用重新定义 ,编译器默认会生成。

class Date
{ 
public :Date* operator&(){return this ;}const Date* operator&()const{return this ;}
private :int _year ; // 年int _month ; // 月int _day ; // 日
};

只有特殊需求,刻意修改取地址操作符,比如此类的地址不外露

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

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

相关文章

汉诺塔问题(C语言)

一&#xff1a;问题 汉诺塔&#xff08;Tower of Hanoi&#xff09;&#xff0c;又称河内塔&#xff0c;是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从…

QVector和QString互相转换

我的画图项目需要读写自定义虚线样式 {...comboBox_penStyle new QComboBox;QStringList SL_penStyle;SL_penStyle << "______" << "----------" << ".........." << "-.-.-.-.-." << "-..-..-..…

【OJ】日期差值与日期累加

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. KY111 日期差值1.1 题目分析1.2 代码 2. KY258 日期累加2.1 题目分析2.2 代码 1. KY111 日期差值 1.1 题目分析 日期之间比较可能会出现给的两个年月日都不相同&#xff0c;这个就不好作差&#xff0c;每个月给的…

LeetCode每日一题 二叉树的最大深度(二叉树)

题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 示例 2&#xff1a; 输入&#xff1a;root [1,nul…

前端知识点、技巧、webpack、性能优化(持续更新~)

1、 请求太多 页面加载慢 &#xff08;webpack性能优化&#xff09; 可以把 图片转换成 base64 放在src里面 减少服务器请求 但是图片会稍微大一点点 以上的方法不需要一个一个自己转化 可以在webpack 进行 性能优化 &#xff08;官网有详细描述&#xff09;

【详识C语言】自定义类型之一:结构体

本文重点 结构体 结构体类型的声明 结构的自引用 结构体变量的定义和初始化 结构体内存对齐 结构体传参 结构体实现位段&#xff08;位段的填充&可移植性&#xff09; 结构体 结构体的声明 结构的基础知识 结构是一些值的集合&#xff0c;这些值称为成员变量。结构的每个…

在 SpringBoot3 中使用 Mybatis-Plus 报错

在 SpringBoot3 中使用 Mybatis-Plus 报错 Property ‘sqlSessionFactory’ or ‘sqlSessionTemplate’ are required Caused by: java.lang.IllegalArgumentException: Property sqlSessionFactory or sqlSessionTemplate are requiredat org.springframework.util.Assert.no…

Vue中有哪些优化性能的方法?

Vue是一款流行的JavaScript框架&#xff0c;用于构建交互性强的Web应用程序。在前端开发中&#xff0c;性能优化是一个至关重要的方面&#xff0c;尤其是当应用程序规模变大时。Vue提供了许多优化性能的方法&#xff0c;可以帮助开发人员提升应用程序的性能&#xff0c;从而提升…

鸿蒙NEXT开发实战:【网络管理-数据请求】

概述 本示例仿postman输入API接口地址&#xff0c;获取相应数据&#xff0c;介绍数据请求接口的用法。 样例展示 基础信息 Http 介绍 本示例通过[ohos.net.http]等接口&#xff0c;实现了根据URL地址和相关配置项发起http请求的功能。 效果预览 首页结果页 使用说明 1.…

重学SpringBoot3-yaml文件配置

重学SpringBoot3-yaml文件配置 引言YAML 基本语法YAML 数据类型YAML 对象YAML 数组复合结构标量引用 YAML 文件结构Spring Boot 中的 YAML 配置注意事项总结参考 引言 YAML&#xff08;YAML Ain’t Markup Language&#xff09;是一种常用于配置文件的数据序列化格式&#xff…

Docker 部署Harbor 443端口冲突

如果Harbor的443端口和主机服务器的443端口存在冲突,那么需要修改Harbor的443 修改docker-compose中443端口,那么需要docker-compose.yml和harbor.yml保持一致配置 当修改harbor.yml重启之后不生效的,则需要进入harbor安装路径 执行 ./install.sh 命令 harbor.yml docker-…

5G智能制造食品工厂数字孪生可视化平台,推进食品行业数字化转型

5G智能制造食品工厂数字孪生可视化平台&#xff0c;推进食品行业数字化转型。随着科技的飞速发展&#xff0c;食品工业正迎来一场前所未有的数字化转型。在这场转型中&#xff0c;5G智能制造工厂数字孪生可视化平台发挥着至关重要的作用。它不仅提高了生产效率&#xff0c;降低…

论文笔记:Compact Multi-Party Confidential Transactions

https://link.springer.com/chapter/10.1007/978-3-030-65411-5_21 A compact, private, Multi-Party Confidential Transactions (MCT) 紧凑型多方机密交易&#xff08;Compact MCT&#xff09;&#xff1a;MCT的长度与常规的单一所有者交易一样短&#xff1b;换句话说&…

前端面试知识点合集(持续性更新)

原型和原型链 任何函数都可以作为构造函数。当该函数通过 new 关键字调用的时候&#xff0c;就称之为构造函数。 var Parent function(){}//定义一个函数&#xff0c;那它只是一个普通的函数&#xff0c;不能称它为构造函数var instance new Parent(); //这时这个Parent就不…

使用vscode前面几行被定住

当我们使用 vscode 滚动代码文档的时候&#xff0c;发现前面几行被定住了&#xff0c;想 css 的 sticky 一样&#xff0c;可能是之前我们不小心点到了这里&#xff0c;取消就好了

SoundTouch对音频处理(Android)

SoundTouch对音频处理&#xff08;Android&#xff09; SoundTouch介绍 SoundTouch 是一个用于音频处理的开源库&#xff0c;主要用于改变音频的速度、音调和音量等特征。您可以在项目中使用 SoundTouch 库来实现音频处理的功能&#xff0c;比如变速播放、音高变化、混响效果…

2024年阿里云服务器配置选择指南_个人和企业如何选择ECS实例规格?

阿里云服务器配置怎么选择&#xff1f;CPU内存、公网带宽和系统盘怎么选择&#xff1f;个人开发者或中小企业选择轻量应用服务器、ECS经济型e实例&#xff0c;企业用户选择ECS通用算力型u1云服务器、ECS计算型c7、通用型g7云服务器&#xff0c;阿里云服务器网aliyunfuwuqi.com整…

亿发生产管控新篇章:mes系统专业推进,引领广州制造厂家数智转型

信息技术在企业发展中扮演着至关重要的角色。然而&#xff0c;随着生产组织方式向多品种、小批量转变&#xff0c;订单不断调整&#xff0c;制定计划需要根据市场和实际作业执行状态&#xff0c;不能仅仅依赖于物料和库存来控制生产。传统的生产现场管理已无法满足当今竞争激烈…

学习计算天数

学习计算天数 题目描述&#xff1a;解法思路&#xff1a;解法代码&#xff1a;运行结果&#xff1a; 题目描述&#xff1a; 输入y和m两个整数&#xff0c;y表示年份&#xff0c;m表示月份&#xff0c;计算y年m月有多少天&#xff0c;并输出天数。 测试1&#xff1a; 输⼊&…

MySQL基础-----SQL语句之DCL数据控制语句

目录 前言 一、管理用户 1.查询用户 2.创建用户 3.修改用户密码 4.删除用户 案例 二、权限控制 1.查询权限 2.授予权限 3.撤销权限 案例 前言 本期我们学习SQL语句的最后一部分内容&#xff0c;也就是数据控制语句DCL。DCL英文全称是Data Control Language(数据控制语…