C++类和对象:构造函数,析构函数,拷贝构造

文章目录

    • 1.类的6个默认成员函数
    • 2. 构造函数
      • 2.1 概念
      • 2.2 特性
    • 3.析构函数
      • 3.1 概念
      • 3.2 特性
    • 4.拷贝构造

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

一个类中什么都不写,就是空类。而空类实际上有成员,当一个类中什么都不写时,编译器会生成六个对应默认成员函数。

默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
在这里插入图片描述
本文先介绍前三个:构造函数,析构函数,拷贝构造

2. 构造函数

2.1 概念

构造函数是一个特殊的成员函数名字与类名相同,创建类类型对象时由编译器自动调用,并且在对象整个生命周期内只调用一次

如有以下Date类:

class Date
{
public:
	Date()
	{
		cout << "调用了构造函数" << endl;
		_year = 1;
		_month = 1;
		_day = 1;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

	int _year;
	int _month;
	int _day;
};

int main()
{
	Date test;
	cout << test._day << " " << test._month << " " << test._year << endl;
	return 0;
}

在这里插入图片描述

Date的对象实例化时,会自动且必须调用构造函数,这里Date的构造函数是使类的属性初始化。

2.2 特性

构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象

特征!

  1. 函数名与类名相同。
  2. 无返回值。
  3. 对象实例化时编译器自动调用对应的构造函数。
  4. 构造函数可以重载,可以多写几个,定义多种初始化方式
//构造函数重载
#include <iostream>
using namespace std;

class Date
{
public:
	Date()
	{
		cout << "调用了无参构造函数" << endl;

	}
	Date(int x)
	{
		cout << "调用了有参构造函数" << endl;
	}
private:

	int _year;
	int _month;
	int _day;
};

int main()
{
	Date test;//调用了无参构造函数
	Date test1(10);//调用了有参构造函数
	return 0;
}
  1. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,这个自动生成的默认构造函数一般不会做任何事(不同的编译器不太一样),一旦用户显式定义编译器将不再生成
class Date
{
public:
	
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	//程序正常运行,因为编译器自动生成无参的构造函数,示例化会使用这个构造函数
	Date d1;
	return 0;
}
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()
{
	// 1. 用户显式定义了构造函数,编译器不会生成默认构造函数
	// 2. 程序不能通过编译,实例化没有适合的构造函数调用
	Date d1;
	return 0;
}
  1. C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明时可以给默认值。
class Date
{
private:
	int _year = 1;
	int _month = 1;
	int _day = 1 ;
};
int main()
{
	Date d1;
	return 0;
}
  1. 如果类中有自定义类型,那么在实例化时会调用自定义类型的构造函数
class Time
{
public:
	Time()
	{
		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;
}
  1. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。注意:无参构造函数全缺省构造函数编译器默认生成的构造函数都可以认为是默认构造函数。总结:不传参数就可以调用的就是默认构造

3.析构函数

3.1 概念

析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。

3.2 特性

  1. 析构函数名是在类名前加上字符 ~
  2. 无参数无返回值类型
  3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载
  4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。并且在同一作用域下,如果有多个类实例化,那么析构函数的调用顺序与构造函数完全相反,这句话用以下代码具体说明:
class A
{
public:
	A()
	{
		cout << "调用了A的析构函数" << endl;
	};
	~A()
	{
		cout << "调用了A的析构函数" << endl;
	}
};
class B
{
public:
	B()
	{
		cout << "调用了B的析构函数" << endl;
	};
	~B()
	{
		cout << "调用了B的析构函数" << endl;
	}
};
class C
{
public:
	C()
	{
		cout << "调用了C的析构函数" << endl;
	};
	~C()
	{
		cout << "调用了C的析构函数" << endl;
	}
};
int main()
{
	A test1;
	cout << "----------------" << endl;
	B test2;
	cout << "----------------" << endl;
	C test3;
	cout << "----------------" << endl;
	return 0;
}

在这里插入图片描述
可以看到程序运行到最后时,A B C 类开始调用他们的析构函数,调用顺序与构造函数完全相反。

  1. 与构造函数类似,默认析构函数对于内置类型不做处理,对于自定义类型会去调用其的析构函数。
  2. 实践中总结:有资源要清理,就写析构。如Stack类。没有资源要清理(如Date类),或者没有内置类型只剩下自定义类型(如MyQueue),用默认生成的析构就可以了。
    在这里插入图片描述

4.拷贝构造

拷贝构造也是一种构造函数,但其构造的形式是以拷贝的方式进行。

  1. 拷贝构造函数是构造函数的一个重载形式
  2. 拷贝构造函数的参数只有一个且必须是该类型对象的引用(Date类举个例子)
class Date
{
public:
	//默认构造函数
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	//拷贝构造
	Date(Date& test)
	{
		_year = test._year;
		_month = test._month;
		_day = test._day;
	}
private:
	int _year;
	int _month;
	int _day;
};

为什么拷贝构造的参数是引用而不是直接传参呢?我们需要了解传自定义类型参数的实质,如果直接传值:

//Date类内
...
Date(Date test)
{
	_year = test._year;
	_month = test._month;
	_day = test._day;
}
...
//main
Date a1;
Date a2(a1);

在这里插入图片描述
同时说明:传入自定义类型作为参数(参数非引用)时,是又创建了个临时类,再调用这个临时类拷贝构造,以你传入的参数作为拷贝构造的参数的。结论:以类为参数的函数,在执行函数时,会调用一次类的拷贝构造

  1. 若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按
    字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
class Date
{
public:
	//默认构造函数
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	//不显示定义拷贝构造 
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date t1;
	Date t2(t1);//使用默认拷贝构造可以实现浅拷贝
}
  1. 类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请
    时,则拷贝构造函数是一定要写的
    ,否则就是浅拷贝。
class Date
{
public:
	
	Date()
	{
		arr = (int*)malloc(20);
		_year = 1;
		_month = 1;
		_day = 1;
	}
	~Date()
	{
		free(arr);
	}
private:
	int _year;
	int _month;
	int _day;
	int* arr;
};

int main()
{
	Date t1;
	//使用默认的拷贝构造,是浅拷贝,t1与t2的arr指针指向同一片空间
	Date t2(t1); 
	//t1与t2最后都调用析构函数,程序崩溃 同一片空间free了两次
	return 0;
}

在这里插入图片描述
5. 拷贝构造函数典型调用场景:

  • 使用已存在对象创建新对象
  • 函数参数类型为类的类型对象
  • 函数返回值类型为类的类型对象
class Date
{
public:
	Date(int year, int minute, int day)
	{
		cout << "Date(int,int,int):" << this << endl;
	}
	Date(const Date& d)
	{
		cout << "Date(const Date& d):" << this << endl;
	}
	~Date()
	{
		cout << "~Date():" << this << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
Date Test(Date d)
{
	Date temp(d);
	return temp;
}
int main()
{
	Date d1(2022, 1, 13);
	Test(d1);
	return 0;
}

在这里插入图片描述
为了提高程序效率,一般对象传参时,尽量使用引用类型,返回时根据实际场景,能用引用
尽量使用引用。

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

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

相关文章

解读我国最新网络安全运维与数据处理安全规范:强化数字化时代安全基石

近日&#xff0c;全国网络安全标准化技术委员会秘书处公布了一系列重要的网络安全与数据安全相关技术规范草案&#xff0c;包括《网络安全技术 网络安全运维实施指南》、《网络安全技术 信息系统灾难恢复规范》以及《数据安全技术 政务数据处理安全要求》。这些规范旨在应对当前…

JavaScript权威指南(第7版) 笔记 - 第 7 章 数组

能用代码说清楚的&#xff0c;绝不多废话&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; Linux创始人Linus的名言&#xff1a;Talk is cheap&#xff0c;show me the code ! &#xff0c;博主技术博文会精心给出能说明问题的范例代码&#xff01;…

安装 k8s集群的问题:默认容器运行时从 Docker 改为 Containerd

安装 k8s集群的问题&#xff1a;默认容器运行时从 Docker 改为 Containerd 1、背景2、容器运行时从 Docker 改为 Containerd2.1、安装 Containerd&#xff1a;2.2、生成 Containerd 的配置文件2.3 、创建 /etc/crictl.yaml 文件2.4 、配置 Containerd 服务开机自启 &#x1f49…

算法与数据结构要点速学——排序算法

排序算法 所有主要的编程语言都有一个内置的排序方法。假设并说排序成本为 O(n*log n)&#xff0c;通常是正确的&#xff0c;其中 n 是要排序的元素数。为了完整起见&#xff0c;这里有一个图表&#xff0c;列出了许多常见的排序算法及其完整性。编程语言实现的算法各不相同&a…

【GDB调试技巧】提高gdb的调试效率

目录 &#x1f31e;gdb的启动 &#x1f31e;gdb技巧 &#x1f33c;1. gdb小技巧汇总 &#x1f33c;2. 打印输出指定地址的值 &#x1f33c;3. 查看当前执行到哪行代码代码内容 3.1 方式一&#xff1a;info line 结合 list 。 3.2 方式二&#xff1a;f 3.3 方式三&#…

WebGIS面试题(第五期)

WebGIS面试题&#xff08;第五期&#xff09; 以下题目仅为部分题目&#xff0c;全部题目在公众号{GISer世界}&#xff0c;答案仅供参考 1、Cesium的核心组件有哪些&#xff1f; Cesium的核心组件包括Viewer、Scene、Model、Geometry、Material和Camera等。其中&#xff0c;…

Latex(从入门到入土)1

第一章&#xff1a;初识Latex 1、安装Latex&#xff0c;当然可以安装官方的开放版本&#xff0c;也可以去找找别人发的资源。我这里只介绍我的学习经过。如果想下载最新的软件资源&#xff0c;我这里推荐微信公众号&#xff1a;软件智库&#xff0c;通过号主提供的网址是可以下…

基于大数据的全国热门景点数据可视化分析系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 本文将介绍如何使用Python中的Pandas库进行数据挖掘&#xff0c;并结合Flask Web框架实现一个旅游景点数据分析系统。该系统将包括以下功能模块&#xff1a;热门景点概况、景点星级与评分分析、景…

Docker 学习笔记(十):Centos7 中 Docker 部署 Redis 集群,打包 SpringBoot 微服务

一、前言 记录时间 [2024-4-17] 系列文章简摘&#xff1a; Docker 学习笔记&#xff08;六&#xff09;&#xff1a;挑战容器数据卷技术一文通&#xff0c;实战多个 MySQL 数据同步&#xff0c;能懂会用&#xff0c;初学必备 Docker 学习笔记&#xff08;七&#xff09;&#x…

基于Copula函数的风光功率联合场景生成_任意修改生成的场景数目(附带Matlab代码)

基于Copula函数的风光功率联合场景生成 削减为6个场景 部分展示削减为5个场景 部分展示 风光等可再生能源出力的不确定性和相关性给系统的设计带来了极大的复杂性&#xff0c;若忽略这些因素&#xff0c;势必会在系统规划阶段引入次优决策风险。因此&#xff0c;在确定系统最佳…

Linux sort/uniq/wc

文章目录 1. sort 排序将线程ID从大到小排序 2.uniq 临近去重3.wc word cnt 统计 1. sort 排序 将线程ID从大到小排序 grep -v是反向筛选&#xff0c;利用USER&#xff0c;排除掉首行 awk是打印第1 2列 sort -n是代码以数值大小做排序&#xff0c;不加的话会以字符排序。 -k是…

Go 单元测试之HTTP请求与API测试

文章目录 一、httptest1.1 前置代码准备1.2 介绍1.3 基本用法 二、gock2.1介绍2.2 安装2.3 基本使用2.4 举个例子2.4.1 前置代码2.4.2 测试用例 一、httptest 1.1 前置代码准备 假设我们的业务逻辑是搭建一个http server端&#xff0c;对外提供HTTP服务。用来处理用户登录请求…

腾讯实验室推出类似 Sora 的长视频生成Mira;阿里巴巴推出强大的代码生成模型CodeQwen1.5

✨ 1: Mira 腾讯PCG ARC实验室推出Mira&#xff1a;类似 Sora 的长视频生成 Mira&#xff08;Mini-Sora&#xff09;&#xff0c;是一个尝试生成高质量、长时视频的初步探索项目&#xff0c;以Sora风格进行长视频生成。与现有的文本到视频&#xff08;Text-to-Video, T2V&a…

2024年【高处安装、维护、拆除】试题及解析及高处安装、维护、拆除模拟试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【高处安装、维护、拆除】试题及解析及高处安装、维护、拆除模拟试题&#xff0c;包含高处安装、维护、拆除试题及解析答案和解析及高处安装、维护、拆除模拟试题练习。安全生产模拟考试一点通结合国家高处安装…

基于SSM+Jsp+Mysql的贝儿米幼儿教育管理系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

如何简单下载指定版本的jdk

Oracle 官方提供的 Java Development Kit (JDK) 的归档站点。它主要用于存放历史版本的 JDK&#xff0c;供开发者下载和使用。 附上站点地址&#xff1a;Archived OpenJDK GA Releases 在这个站点可以找到各版本的jdk&#xff0c;简单实用~ 找到版本&#xff0c;点击tar.gz进…

研究表明,全球互联网流量竟有一半来自机器人

据Cyber News消息&#xff0c;Thales Imperva Bad Bot近期做了一份报告&#xff0c;显示在2023年有49.6%的互联网流量竟来自机器人&#xff0c;比上一年增长 2%&#xff0c;达到自2013年以来观察到的最高水平。 报告称&#xff0c;这一趋势正对企业组织产生负面影响&#xff0c…

Qwen1.5大语言模型微调实践

在人工智能领域&#xff0c;大语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;的兴起和广泛应用&#xff0c;为自然语言处理&#xff08;NLP&#xff09;带来了前所未有的变革。Qwen1.5大语言模型作为其中的佼佼者&#xff0c;不仅拥有强大的语言生成和理…

Seata

Seata是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata将为用户提供了AT、TCC、SAGA和XA事务模式&#xff0c;为用户打造一站式的分布式解决方案。 1.1 Seata的三大角色 在 Seata 的架构中&#xff0c;一共有三个角色&#xff1…

解决 MSYS2 Qt 6.7 默认 stylesheet 在 windows 11 下的显示故障

项目场景&#xff1a; MSYS2 升级到 Qt6.7.0&#xff0c;发现显示故障&#xff0c;所有Qt6程序以及 QtCreator的SpinBox都显示不全&#xff0c;Combox的底色不对。 问题描述 2024年4月1日&#xff0c;pacman升级MSYS2后&#xff0c;Qt6遇到风格错误。如果使用官方的 Qt onlin…