C++回顾(五)—— 构造函数和析构函数

news2024/9/30 21:34:08

5.1 构造和析构

5.1.1 构造函数

(1)定义

  • 1)C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数
  • 2)构造函数在定义时可以有参数;
  • 3)没有任何返回类型的声明。

(2)调用

  • 自动调用:一般情况下C++编译器会自动调用构造函数;
  • 手动调用:在一些情况下则需要手工调用构造函数。

5.1.2 析构函数

(1)定义

  • 1)C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫做析构函数
    语法:~ClassName()
  • 2)析构函数没有参数也没有任何返回类型的声明

(2)调用

  • 析构函数在对象销毁时自动被调用

5.1.3 对象的构造和析构

(1)构造函数的分类

  • 无参构造函数
  • 有参构造函数
  • 理解对象的初始化与对象赋值的不同
Test t1(4,5);
Test t2 = Test(5,6);  // 对象的初始化
t2 = t1;              // 对象的赋值
  • 拷贝构造函数
  • 默认构造函数
    二个特殊的构造函数
    1)默认无参构造函数
    当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空
    2)默认拷贝构造函数
    当类中没有定义拷贝构造函数时,编译器默认提供一个默认拷贝构造函数,简单的进行成员变量的值复制

(2)构造函数的规则

  • 1)当类中没有定义任何一个构造函数时,c++编译器会提供默认无参构造函数和默认拷贝构造函数
  • 2)当类中定义了拷贝构造函数时,c++编译器不会提供无参数构造函数
  • 3)当类中定义了任意的非拷贝构造函数(即:当类中提供了有参构造函数或无参构造函数),c++编译器不会提供默认无参构造函数
  • 4 )默认拷贝构造函数成员变量简单赋值

总结:只要你写了构造函数,那么你必须用。

#include <iostream>

using namespace std;

class Test1
{
public:
};

class Test2
{
public:
	Test2()
	{
		cout << "Test2无参构造函数" << endl;
	}
};

class Test3
{
public:
	Test3(int a)
	{
	}
};

class Test4
{
public:
	Test4(const Test4 &t)
	{
	}
};

int main()
{
	Test1 t1;   //编译器会默认提供无参构造函数
	Test1 tt(t1);  //编译器提供默认的拷贝构造函数(浅拷贝)
	Test2 t2;   //一旦提供了无参构造函数,编译器不再提供默认无参构造函数
	//Test3 t3;   //一旦提供了有参构造函数,编译器不再提供默认无参构造函数(所有这里会报错)
	//Test4 t4;    //一旦提供了拷贝构造函数,编译器不再提供无参构造函数(所有这里会报错)

	return 0;
}

运行结果:
在这里插入图片描述

(3)构造析构阶段性总结

  • 1)构造函数是C++中用于初始化对象状态的特殊函数
  • 2)构造函数在对象创建时自动被调用
  • 3)构造函数和普通成员函数都遵循重载规则
  • 4)拷贝构造函数是对象正确初始化的重要保证
  • 5)必要的时候,必须手工编写拷贝构造函数
#include <iostream>
#include <cstdlib>

using namespace std;

class Array
{
private:
	int *data;   //数组的起始地址
	int size;    //数组的容量
public:
	Array();      //无参构造函数 函数名和类名一样  没有返回值  完成对象的初始化操作
	Array(int s); //有参构造函数
	Array(const Array &a);   //拷贝构造函数
	void setVal(int Index, int val);
	int getVal(int Index);
	~Array();     //析构函数 函数名是类名加~  没有参数 没有返回值
};

Array::Array()
{
	cout << "Array的无参构造函数" << endl;
	size = 5;
	data = (int *)malloc(sizeof(int) * size);
}

Array::Array(int s)
{
	cout << "Array的有参构造函数" << endl;
	size = s;
	data = (int *)malloc(sizeof(int) * size);
}

Array::Array(const Array &a)
{
	cout << "Array的拷贝构造函数" << endl;
}

void Array::setVal(int Index, int val)
{
	data[Index] = val;
}

int Array::getVal(int Index)
{	
	return data[Index];
}

Array::~Array()
{
	cout << "Array析构函数" << endl;
	if (data != NULL)
	{
		free(data);
	}
}

void f(Array a)
{
	
}

int main()
{
	Array a1;     //创建对象的时候,自动调用构造函数
	Array a2(10);//有参构造函数(这个用的最多)
	Array a3 = Array(10);
	Array a4 = (10);
	
	for (int i = 0; i < 5; i++)
	{
		a1.setVal(i, i + 1);
	}

	for (int i = 0; i < 5; i++)
	{
		cout << a1.getVal(i) << " ";
	}
	cout << endl;

	cout << "********" << endl;
	f(a1);      //函数传参,会调用拷贝构造函数
	//Array a5(a2);   //调用拷贝构造函数  用a2构造a5

	return 0;     //释放对象的时候,自动调用析构函数
}

运行结果:
在这里插入图片描述

5.2 深拷贝和浅拷贝

5.2.1 浅拷贝问题分析

完成数组类,主函数调用拷贝构造函数,观察代码会出现什么问题?

默认复制构造函数可以完成对象的数据成员值简单的复制
对象的数据资源是由指针指示的堆时,默认复制构造函数仅作指针值复制

注意:这样在析构的时候,会出现释放两次空间的情况,出现报错

5.2.2 浅拷贝问题解决:深拷贝

#include <iostream>
#include <stdlib.h>

using namespace std;

class Array
{
private:
	int *data;
	int size;
public:
	Array(int s)
	{
		cout << "有参构造函数" << endl;
		size = s;
		data = (int *)malloc(sizeof(int) * size);
	}
	Array(const Array &a)    //深拷贝
	{
		cout << "Array拷贝构造函数" << endl;
		size = a.size;
		data = (int *)malloc(sizeof(int) * size);
		for (int i = 0; i < size; i++)
		{
			data[i] = a.data[i];
		}
	}
	~Array()
	{
		cout << "析构函数" << endl;
		if (data != NULL)
		{
			free(data);
		}
	}
};

int main()
{
	Array a1(10);
	Array a2(a1);  //编译器为每个类提供默认的拷贝构造函数 只做简单的赋值(浅拷贝)

	return 0;
}

运行结果:
在这里插入图片描述

5.3 匿名对象

#include <iostream>

using namespace std;

class Test
{
public:
	Test()
	{
		cout << "Test无参构造函数" << endl;
	}
	~Test()
	{
		cout << "Test析构函数" << endl;
	}
};

int main()
{
	Test();   //匿名对象,本行代码执行完,立即被释放
	Test();

	return 0;
}

运行结果:
在这里插入图片描述

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

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

相关文章

第十届蓝桥杯省赛——5最大降水量(纯填空,分析)

题目&#xff1a;试题 E: 最大降雨量本题总分&#xff1a;15 分【问题描述】由于沙之国长年干旱&#xff0c;法师小明准备施展自己的一个神秘法术来求雨。这个法术需要用到他手中的 49 张法术符&#xff0c;上面分别写着 1 至 49 这 49 个数字。法术一共持续 7 周&#xff0c;每…

二叉树——二叉树的最近公共祖先

二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一…

如何使用DDexec在Linux上隐蔽运行二进制文件

关于DDexec DDexec是一种能够在Linux上使用无文件技术和隐秘技术运行二进制文件的方法&#xff0c;它可以使用dd工具来将Shell替换为其他进程。 众所周知&#xff0c;在Linux上运行一个程序&#xff0c;则这个程序必须以一个文件的形式存在&#xff0c;而且必须能够通过文件系…

电脑没有回收站找回删除文件的2种方法

最近后台收到了这样的咨询&#xff1a;”在网吧上网&#xff0c;删除东西的时候不小心把我的文件给删除了&#xff0c;但是桌面上没有回收站&#xff0c;怎么才能找回我的文件&#xff1f;“——针对“电脑没有回收站删除的东西怎么恢复”这种疑问&#xff1f;不妨看看下面数据…

环境搭建02-Ubuntu16.04 安装CUDA和CUDNN、CUDA多版本替换

1、CUDA安装 &#xff08;1&#xff09;下载需要的CUDA版本 https://developer.nvidia.com/cuda-toolkit-archive &#xff08;2&#xff09;安装 sudo sh cuda_8.0.61_375.26_linux.run&#xff08;3&#xff09;添加环境 gedit ~/.bashrc在文件末尾添加&#xff1a; ex…

【小程序】已有公众号认证,一步一步申请小程序(图文)

一、登陆公众号后台&#xff0c;找到左侧广告与服务&#xff0c;小程序管理&#xff0c;开通 二、选择快速注册认证小程序 三、快速创建 四、选择微信认证资质&#xff08;复用&#xff09;&#xff0c;这样不用再付认证费了 五、需要一个新的邮箱&#xff0c;这点挺让人无语&a…

【Hello Linux】进程优先级和环境变量

作者&#xff1a;小萌新 专栏&#xff1a;Linux 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;简单介绍下进程的优先级 环境变量 进程优先级环境变量进程的优先级基本概念如何查看优先级PRI与NINI值的设置范围NI值如何修改修改方式…

PT100铂电阻温度传感器

PT100温度传感器又叫做铂热电阻。     热电阻是中低温区&#xfe61;常用的一种温度检测器。它的主要特点是测量精度高&#xff0c;性能稳定。其中铂热电阻的测量精确度是&#xfe61;高的&#xff0c;它不仅广泛应用于工业测温&#xff0c;而且被制成标准的基准仪。金属热…

此网站可能不支持TLS1.2协议

问题描述 火狐浏览器版本&#xff1a;“97.0.1 (64 位)”&#xff0c;打开360网神设备Web管理地址时出现&#xff1a;“此网站可能不支持TLS1.2协议&#xff0c;而这是Firefox支持的最低版本。”&#xff0c;如下图所示。 原本是默认使用https协议打开的&#xff0c;看起来出问…

Ep_操作系统面试题-什么是线程,线程和进程的区别

1. 一个进程中可以有多个线程,多个线程共享进程的堆和方法区 (JDK1.8 之后的元空间),但是每个线程有自己的程序计数器、虚拟机栈和 本地方法栈。 2.进程是资源分配的最小单位&#xff0c;线程是CPU调度的最小单位 视频讲解: https://edu.csdn.net/course/detail/38090 点我…

CSS简单使用

凡是html中的标签都可以进行选中&#xff0c;p代表标签中所有的p标签都遵从以上格式。<!DOCTYPE html> <html lang"en"> <head><style type"text/css">p{background-color: red;font-size: 40px;}.p1{font-family:楷体;}</styl…

爆!!!2023《TikTok美妆个护行业分析报告》重磅出炉,掌握趋势加速出海变现!

2022年是中国化妆品零售行业的拐点之年&#xff0c;零售总额跌破4000亿元大关&#xff0c;是13年来的首次下滑。随着国内消费者对化妆品支出的放缓&#xff0c;越来越多的美妆个护国牌选择出海寻找第二增长曲线&#xff0c;而新渠道如TikTok 等电商平台的崛起&#xff0c;也为出…

ECharts教程(详细)

ECharts教程(详细) 非常全面的ECharts教程&#xff0c;非常全面的ECharts教程&#xff0c;目前线条/节点颜色、线条粗细、线条样式、线条阴影、线条平滑、线条节点大小、线条节点阴影、线条节点边框、线条节点边框阴影、工具提醒、工具提醒样式、工具自定义提醒、工具提醒背景…

云Windows Server 2022 Datacenter 安装MySQL8解压缩版 mysql-8.0.32-winx64 230301记录

MySQL Community Downloads MySQL社区版压缩包下载地址 https://dev.mysql.com/downloads/mysql/ 解压到了C盘 没打算设置环境变量 右键点击开始 或 winx 以管理员身份打开 PowerShell 进入到安装目录下的 bin 目录 可以输入cd 后&#xff0c; 拖动 bin 文件夹到控制台&…

二分算法题

文章目录一、在排序数组中查找数字二、0~n-1中缺失的数字三、旋转数组的最小数字四、二维数组中的查找一、在排序数组中查找数字 题目传送门 法一&#xff1a;暴力解 直接遍历然后计数 法二&#xff1a;二分法求边界 看到关键字排序数组、有序数组&#xff0c;一定要想到二分…

Nacos2.x+Nginx集群配置

一、配置 nacos 集群 注意&#xff1a;需要先配置好 nacos 连接本地数据库 1、拷贝三份 nacos 2、修改配置文件&#xff08;cluster.conf&#xff09; 修改启动端口&#xff1a; nacos1&#xff1a;8818 nacos2&#xff1a;8828 nacos3&#xff1a;8838 当nacos客户端升级为…

Linux-0.11 kernel目录fork.c详解

Linux-0.11 kernel目录fork.c详解 fork.c中主要实现内核对于创建新的进程的行为。其中copy_process是其最核心的函数。 copy_process int copy_process(int nr,long ebp,long edi,long esi,long gs,long none,long ebx,long ecx,long edx,long fs,long es,long ds,long eip,…

如何使用Coercer强制Windows Server认证任意主机

关于Coercer Coercer是一款功能强大的Python脚本&#xff0c;该工具可以通过九种不同的方法来强制让一台Windows Server认证任意主机。 功能介绍 1、自动检测远程设备的开放SMP管道&#xff1b; 2、一一调用存在安全漏洞的RPC功能来强制一台Windows Server认证任意主机&#…

字节二面,原来是我对自动化测试的理解太浅薄了..

如何使用Python实现自动化测试 如果你入职一家新的公司&#xff0c;领导让你开展自动化测试&#xff0c;作为一个新人&#xff0c;你肯定会手忙脚乱&#xff0c;你会如何落地自动化测试呢&#xff1f;资深测试架构师沉醉将告诉你如何落地自动kan化测试&#xff0c;本次话题主要…

什么是链表,如何实现?(单链表篇)

欢迎来到 Claffic 的博客 &#x1f49e;&#x1f49e;&#x1f49e; “仅仅活着是不够的&#xff0c;还需要有阳光&#xff0c;自由和花的芬芳。” 前言&#xff1a; 在日常使用的网站和软件中&#xff0c;列表属于最常见的一种东西了&#xff0c;其实现形式有顺序表&#xff0…