【C++】类和对象(三)构造与析构

文章目录

  • 一、类的6个默认成员函数
  • 二、 构造函数
    • 干嘛的?
    • 语法定义
    • 特性
      • 综上总结
      • 什么是默认构造函数?
  • 三、析构函数
    • 干嘛的 ?
    • 语法定义
    • 析构顺序

一、类的6个默认成员函数

如果一个类中什么成员都没有,简称为空类。空类中并不是真的什么都没有。任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。
默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。

在这里插入图片描述

二、 构造函数

干嘛的?

构造函数是特殊的成员函数 用来初始化对象

语法定义

1️⃣函数名和类名相同
2️⃣没有返回值(不需要写)
代码演示:

class Date
{
public:
	//函数名与类名相同 没有返回值 不用写void 
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}

	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1;
	d1.Print();
	return 0;
}

3️⃣对象实例化时 编译器自动调用该函数,如果没有构造函数可调,会报错。
反汇编演示自动调用:
在这里插入图片描述
4️⃣构造函数可以重载(重载:函数名相同,参数不同)

class Date
{
public:
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	//构造函数可以重载
	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 d1;
	d1.Print();
	Date d2(2024, 1, 27);
	d2.Print();
	return 0;
}

在这里插入图片描述

注意:无参的构造函数 和 全缺省的构造函数 可以同时存在类的定义里,但一般不这样写,因为调用会存在 歧义。

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

int main()
{
	Date d1;
	Date d2(2024, 1, 27);
	return 0;
}

比如会出现如下报错:
在这里插入图片描述
构造函数可以带参数、也可以不带参数
带参数的情况:实例化对象时,直接把参数跟在对象后面就可以。
无参数的情况:实例化对象时,不能跟空括号()在对象后面,原因是:改写法无法跟函数声明区分开。

实践中,更多的情况直接用全缺省的构造函数

特性

思考下面的日期类我们没提供构造函数的情况是否会被初始化?

class Date
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1;
	d1.Print();
}

在这里插入图片描述

1、构造函数 ,是默认成员函数,程序员不写,编译器会生成一个,但是自动生成的构造函数初始化出的成员变量没有默认值(具体根据成员变量的类型而定)。

tips:C++ 中 数据类型分为

内置类型(基本类型): int /char /doube/指针… 语言自身定义的类型
自定义类型: struct /class

C++98 规定 ,编译器自动生成的 构造函数 对于内置类型不做处理,自定义类型会去调用他的默认构造函数。
演示代码:

class A
{
public:
	A()
	{
		cout << "A()" << endl;
		_a = 0;
	}
private:
	int _a;
};

class Date
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	// 内置类型 不做处理
	int _year ;
	int _month ;
	int _day;
	// 自定义类型 调默认构造
	A _aa;
};
int main()
{
	Date d1;
	d1.Print();
}

在这里插入图片描述

C++11 委员会对这个语法进行打补丁,对于内置类型 在成员变量声明位置 可以给缺省值 ,编译器自动生成的构造函数就会用程序员给出的这个缺省值初始化成员变量。

class A
{
public:
	A()
	{
		cout << "A()" << endl;
		_a = 0;
	}
private:
	int _a;
};

class Date
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	// C++11 内置类型 声明位置可以给缺省值
	int _year =1;
	int _month =1;
	int _day;
	// 自定义类型 调默认构造
	A _aa;
};
int main()
{
	Date d1;
	d1.Print();
}

在这里插入图片描述

综上总结

编译器自动生成的构造函数 在进行对象实例化时 对成员变量的初始化操作:

若成员变量是内置类型:编译器不做处理,程序员可以在成员变量声明位置 可以给缺省值 ,编译器自动生成的构造函数就会用程序员给出的这个缺省值初始化成员变量。

若成员变量是自定义类型:编译器自动生成的构造函数就会调用他的默认构造函数

程序员需要自己分析类型成员和初始化需求,绝大多数场景都需要程序员自己实现构造函数!

什么是默认构造函数?

编译器自动生成的构造函数只是 默认构造函数之一。无参数的构造函数全缺省的构造函数 也属于默认构造函数

总结:不需要传参 就可以调用的构造函数 ➡️默认构造函数,默认构造函数只能有一个

❓问题遗留:

class Time
{
public:
	// 没有默认构造函数
	Time(int hour)
	{
		cout << "Time()" << endl;
		_hour = 0;
		_minute = 0;
		_second = 0;
	}
private:
	int _hour;
	int _minute;
	int _second;
};

class Date
{
private:
	// 基本类型(内置类型)
	int _year;
	int _month;
	int _day;

	// 自定义类型
	Time _t;
}

int main()
{
	Date d;

	return 0;
}

代码问题描述:
当前time类中 我们显示定义了构造函数 ,则编译器不会自动生成默认构造函数。Data类包含time类,time类没有默认构造函数,导致Data类编译器也无法为这个类自动生成默认构造函数。

报错如下:在这里插入图片描述
此时,我们只能显示实现构造函数,详见 下期知识点初始化列表

三、析构函数

干嘛的 ?

清理资源,类似于 Desdory .

语法定义

1、析构函数名实在类名前面加上~

2、无参数无返回值类型

3、一个类只能有一个析构函数。程序员没定义,编译器自动生成析构函数。析构函数不能重载。

4、对象声明周期结束的时候,编译器自动调用

因为在函数栈帧里,所以先定义的后析构后定义的先析构

代码示例:我们创建不同生命周期不同作用域的对象,注意观察他们的析构顺序

#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year = 1)
	{
		_year = year;
	}

	~Date()
	{
		cout << "~Date()->"<<_year<< endl;
	}

private:
	// 基本类型(内置类型)
	int _year;
	int _month;
	int _day;
};
void func()
{
	Date d3(3);
	static Date d4(4);
}

Date d5(5);
static Date d7(7);
Date d6(6);
static Date d8(8);

// 局部对象(后定义先析构) -》 局部的静态 -》全局对象(后定义先析构)
int main()
{
	Date d1(1);
	Date d2(2);
	func();

	return 0;
}

析构顺序

局部对象(后定义先析构) ➡️ 局部的静态 ​ ➡️ 全局对象(无论静态or非静态 都是后定义先析构)

在这里插入图片描述

默认生成的析构函数跟构造函数类似,

如果要清理的资源是内置类型,则不做处理。若是自定义类型的成员,则编译器去调用它的析构函数

其他的默认成员函数我们会在下节介绍~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

不懂索引,简历上都不敢写自己熟悉SQL优化

大家好&#xff0c;我是考哥。 今天给大家带来MySQL索引相关核心知识。对MySQL索引的理解甚至比你掌握SQL优化还重要&#xff0c;索引是优化SQL的前提和基础&#xff0c;我们一步步来先打好地基。 当MySQL表数据量不大时&#xff0c;缺少索引对查询性能的影响不会太大&#x…

在react项目中让webpack使用mock数据

1. 创建react项目 使用 create-react-app 创建项目 npx create-react-app react-mock 执行 eject 命令 npm run eject 删除 package.json 文件中的 eslintConfig 选项 2. 安装依赖包 npm i path-to-regexp fast-glob chokidar axios 3. 创建中间件 在 config 文件夹中创…

Android【SDK】 SDK是如何开发的,怎么打包aar包

文章目录 一、Android SDK开发示例工程二、Android SDK的开发三、打包aar包四、Android SDK的使用 一、Android SDK开发示例工程 本教程工程Git链接&#xff1a;https://gitcode.com/xiaohuihui1400/AndroidSdkExample/overview 二、Android SDK的开发 新建项目&#xff0c;…

Linux驱动开发笔记(九)IIC子系统及其驱动

文章目录 前言一、IIC驱动框架二、总线驱动2.1 iic总线的运行机制2.2 重要数据结构2.2.1 i2c_driver结构体2.2.2 i2c总线结构体 2.3 匹配规则 三、设备树的修改四、设备驱动的编写4.1 相关API函数4.1.1 i2c_add_adapter( )4.1.2 i2c_register_driver( )4.1.3 i2c_transfer( )4.…

MDK-ARM 编译后 MAP 文件分析

本文配合 STM32 堆栈空间分布 食用更佳&#xff01; 一图胜千言。。。

【LLM之NL2SQL】DAIL-SQL论文阅读笔记

研究背景 该研究旨在提供一个全面、系统的评估框架&#xff0c;用于评估基于大型语言模型&#xff08;LLM&#xff09;的Text-to-SQL技术。特别强调了不同的提示工程策略的有效性和效率&#xff0c;以及开源LLM的可行性。研究的重点是评估在零样本和少样本场景下的不同问题表示…

ICC2如何写DCG需要的floorplan信息

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 DCG需要哪些floorplan信息呢? 1)fixed属性的port和mem / ip / io 2)boundary信息 3)电源域形状 前两条都可以写到def里,电源域需要用脚本处理,这里分享一下脚本。 set_fixed_objects [ge…

# 消息中间件 RocketMQ 高级功能和源码分析(七)

消息中间件 RocketMQ 高级功能和源码分析&#xff08;七&#xff09; 一、 消息中间件 RocketMQ 源码分析&#xff1a;消息存储核心类介绍 1、消息存储在 store 模块中。消息存储核心类 DefaultMessageStore.java 2、消息存储核心类介绍 private final MessageStoreConfig me…

react18 实现具名插槽

效果预览 技术要点 当父组件给子组件传递的 JSX 超过一个标签时&#xff0c;子组件接收到的 children 是一个数组&#xff0c;通过解析数组中各 JSX 的属性 slot &#xff0c;即可实现具名插槽的分发&#xff01; 代码实现 Father.jsx import Child from "./Child";…

DNF安卓分离仅是开始:游戏厂商积极布局自有渠道,市场变革在即

毫无征兆&#xff0c;DNF手游今天突然宣布从各大安卓平台下架。 《地下城与勇士:起源》运营团队于6月19日发布声明&#xff0c;指出因合约到期&#xff0c;游戏将不再上架部分安卓平台的应用商店。然而&#xff0c;这一事件并非完全无迹可循。 早在2021年初&#xff0c;华为游…

ROM以及ROM与RAM对比

1.ROM ROM最原始的定义是“只读存储器”&#xff0c;一旦写入原始信息则不能更改。所以ROM通常用来存放固定不变的程序、常数和汉字字库&#xff0c;甚至用于操作系统的固化。它与随机存储器可共同作为主存的一部分&#xff0c;统一构成主存的地址域。 现在已经发展出了很多R…

商超便利店收银系统源码推荐

细节决定成败&#xff0c;无论是做什么事情都要注重细节&#xff0c;让我们来看看关于商超便利店陈列的“细节”有哪些需要注意的地方。 首先要注意商品不要摆太高&#xff0c;放在适当位置即可&#xff01; 商超便利店内&#xff0c;销量最佳的物品摆放位置依次为与顾客视线…

ICC2如何写出floorplan信息

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 1)write_def 不用-exclude 的话rows_tracks / vias /blockages / routing_rules信息都会写出去,即便用了-include {macro ports}也不行,所以不介意这些东西的话可以用以下两种种def方式去写f…

RabbitMQ的简单使用 —— Python篇

&#xff08;一&#xff09;RabbitMQ的简介 RabbitMq 是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理中间件。消息队列是一种应用程序对应用程序的通行方式&#xff0c;应用程序通过写消息&#xff0c;将消息传递于队列&#xff0c;由另一应用程序读取 完…

nacos 配置修改.代码实时刷新

再类上用 RefreshScope 更新Value(“${uniqlo.privacy.url:https://wsurl.cc/yourls-api.php}”) private String shortLinkGenerateUrl;的数据可以实时更新 2.再配置类上次用 ConfigurationProperties(prefix “test.privacy”) 和nacos的配置一直 Data Component Configu…

redis高可用-哨兵机制

一&#xff1a;背景 上一节我们已经实现了redis的主从同步&#xff0c;从而实现服务的流量分摊和数据高可用&#xff0c;但是出现故障以后&#xff0c;需要人工手动接入&#xff0c;手动切换主从&#xff0c;来实现故障转移。这是比较麻烦的&#xff0c;毕竟人不能实时盯着服务…

深度学习算法informer(时序预测)(四)(Decoder)

一、DecoderLayer架构如图&#xff08;不改变输入形状&#xff09; 二、Decoder整体 包括两部分 1. 多层DecoderLayer 2. 层归一化 代码如下 class DecoderLayer(nn.Module):def __init__(self, self_attention, cross_attention, d_model, d_ffNone,dropout0.1, activati…

java溯本求源之基础(二十五)之--ArrayList常用方法介绍

1. 介绍 1.1简介 ArrayList ArrayList 是 Java 集合框架中的一个类&#xff0c;位于 java.util 包中。它实现了 List 接口&#xff0c;提供了一个动态数组的功能。与普通数组不同&#xff0c;ArrayList 可以在需要时自动调整其容量&#xff0c;以容纳更多的元素。这使得它非常…

《模拟联合国2.9—团队协作》

感谢上海财经大学持续的邀请&#xff0c;今天在阶梯教室举办的《模拟联合国2.0—团队协作》沙盘课程圆满结束。尽管场地的限制带来了一定的挑战&#xff0c;但得益于系统思考中“结构影响行为”的原则&#xff0c;我得以在不同场景中巧妙设计课程结构&#xff0c;极大地促进了大…

【SEMI-e ·国际半导体深圳展】| 06月26-28日唯创知音语音芯片供应商 邀您来观展

世界聚焦半导体&#xff0c;产业规模空前&#xff01;一场高端产业研学盛会即将如约而至。 SEMI-e 第六届2024国际半导体展深圳站&#xff0c;2024年06月26-28日将在深圳国际会展中心&#xff08;宝安&#xff09;开展&#xff0c;展会展出面积60000平方米&#xff0c;汇聚全国…