20240415,构造函数和析构函数,拷贝构造函数调用时机规则

二,对象的初始化和清理

2.1 构造函数和析构函数

解决初始化和清理问题,编译器自动调用,如果不提供,编译器提供,但空实现 
构造函数类名(){ };没用返回值也不写VOID,函数名称和类名称相同,可以有参数,可以发生重载,自动调用且只一次调用构造
析构函数:~类名 ( ){ };两点特性同上,无参数且不可重载,程序在对象销毁前自动且仅一次调用析构

#include<iostream>
using namespace std;
//对象的初始化和清理
//构造··,无返,类名,有参,自动
//析构··,无返,类名,无参,自动
class Person
{
public:
	Person()
	{
		cout << "Person 构造函数的调用" << endl;
	}
	~Person()
	{
		cout << "Person 析构函数的调用" << endl;
	}
};
void test01()//创建对象,但是没有调用类的函数
{
	Person p;//局部变量,栈上的数据,TEST01执行完毕后,释放这个对象
}
int main()
{
	test01();//
	cout << endl;
	static Person p1;
	
	system("pause");//PAUSE是暂停的意思,此时MAIN函数没有结束,P1没有被释放
	return 0;//结束main函数,返回0
}
2.2 函数分类及调用

分类::参数:有参&无参构造;类型:普通&拷贝构造
​​​​​​​调用方式::括号,显示,隐式转换

#include<iostream>
using namespace std;
class Person
{
public:
	//普通
	Person()//无参,默认
	{
		cout << "Person 无参构造函数的调用" << endl;
	}
	Person(int a)
	{
		age = a;
		cout << "Person 有参构造函数的调用" << endl;
	}
	//拷贝
	Person(const Person& p)//将传入人的所有属性拷贝到我身上?
	{
		age = p.age;
		cout << "Person 拷贝构造函数的调用" << endl;
	}
	~Person()
	{
		cout << "Person 析构函数的调用" << endl;
	}
	int age;
};
//调用
void test01()
{
	//括号
	Person p1;//默认无参     不能加括号,PERSON P1();会被认为是一个函数的声明,不会被认为在创建对象
	Person p2(10);//有参
	Person p3(p2);//拷贝
	//函数结束一起释放
	cout << "P2年龄是" << p2.age << endl;
	cout << "P3年龄是" << p3.age << endl;
}
void test02()
{
	//显示法
	Person p1;
	Person p2 = Person(10);//有参构造调用
	Person p3 = Person(p2);//拷贝··    
	Person(10);//匿名构造,当前行执行结束后,系统会立即回收匿名对象
	cout << "aaa" << endl;
	//Person(p3);
	//不要用拷贝构造函数,初始化对象,编译器认为  Person (p3)==Person p3;一个对象声明
}
void test03()
{
	//隐式转换法
	Person p1 = 10;//Person p1=Person(10)有参
	Person p2 = p1;//拷贝
}
int main()
{
	test01();
	cout << endl;
	test02();
	cout << endl;
	test03();
	system("pause");
	return 0;
}
2.3 拷贝构造函数调用时机

使用一个已经创建完毕的对象来初始化一个新对象
值传递的方式给函数参数传值
值方式返回局部对象(有点问题,老师讲的和我的结果有出入,没没有调用成功)-我的编译是将函数返回的PERSON当作一个常量值,而不是一个PERSON

#include<iostream>
using namespace std;
class Person
{
public:
	Person()
	{
		cout << "Person 默认构造函数的调用" << endl;
	}
	Person(int a)
	{
		cout << "Person 有参构造函数的调用" << endl;
		age = a;
	}
	Person(const Person& p)
	{
		cout << "Person 拷贝构造函数的调用" << endl;
		age = p.age;
	}
	~Person()
	{
		cout << "Person 析构函数的调用" << endl;
	}
	int age;
};

void test01()//使用一个已经创建完毕的对象来初始化一个新对象
{
	Person p1(20);
	Person p2(p1);
	cout << "p2的年龄" << p2.age << endl;
}
void dowork(Person p)
{
	
}
void test02()//值传递的方式给函数参数传值
{
	Person p;
	dowork(p);//P对象值传入函数,Person p=p;(隐式转换法,乐)产生形参的时候构造析构了一下?
}
Person dowork2()
{
	Person p;
	cout << (int*) & p << endl;//打印地址
	return p;
}
void test03()//值方式返回局部对象
{
	Person p(dowork2());//只调用了一次?
	cout << (int*)&p << endl;
	Person p1 = dowork2();//还是一次
	//以上都没用触发拷贝函数,而是默认函数,dowork2()虽然是返回一个Person,但是算值????
	cout << (int*)&p1 << endl;
	cout << endl;
	Person p2(p);
	//前两个地址相同,P2的地址不同,乐
	cout << (int*)&p2 << endl;

}
int main()
{
	test01();
	cout << endl;
	test02();
	cout << endl;
	test03();
	system("pause");
	return 0;
}
2.4 构造函数调用规则

默认情况下,C++编译器至少给一个类添加三个函数:默认构造(无参,函数体为空);默认析构(无参,函数体为空);默认拷贝构造,对属性进行值拷贝

规则:如果用户定义有参构造函数,C++不再提供默认无参构造,但会提供默认拷贝构造
如果用户定义拷贝构造函数,C++不会再提供其他构造函数

#include<iostream>
using namespace std;

class Person
{
public:
	//Person()//运行test01不能注释
	如果用户定义有参构造函数,C++不再提供默认无参构造,但会提供默认拷贝构造
	//{
	//	cout << "Person 默认构造函数的调用" << endl;
	//}
	Person(int a)
	{
		cout << "Person 有参构造函数的调用" << endl;
		age = a;
	}
	/*Person(const Person& p)
	{
		cout << "Person 拷贝构造函数的调用" << endl;
		age = p.age;
	}*/
	~Person()
	{
		cout << "Person 析构函数的调用" << endl;
	}
	int age;
};

//void test01()
//{
//	Person p;
//	p.age = 18;
//	Person p1(p);
//	cout << "p1的年龄" << p1.age << endl;
//}
void test02()//运行test02可以注释,
{
	Person p(20);
	Person p1(p);
	cout << "p1的年龄" << p1.age << endl;
}
int main()
{
	//test01();
	cout << endl;
	test02();
	system("pause");
	return 0;
}
#include<iostream>
using namespace std;

class Person
{
public:
	/*Person()
	{
		cout << "Person 默认构造函数的调用" << endl;
	}
	Person(int a)
	{
		cout << "Person 有参构造函数的调用" << endl;
		age = a;
	}*/
	Person(const Person& p)
	{
		cout << "Person 拷贝构造函数的调用" << endl;
		age = p.age;
	}
	~Person()
	{
		cout << "Person 析构函数的调用" << endl;
	}
	int age;
};

void test03()//如果用户定义拷贝构造函数,C++不会再提供其他构造函数
{
	Person p;
	Person p(10);
}
int main()
{
	test03();
	system("pause");
	return 0;
}

 

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

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

相关文章

spring03:bean的自动装配

spring03&#xff1a;bean的自动装配 文章目录 spring03&#xff1a;bean的自动装配前言&#xff1a;一、 在xml中显示的配置&#xff1a;分析&#xff1a; People类&#xff1a;Cat类&#xff1a;Dog类&#xff1a;1. 在xml中显示的配置&#xff1a; 二、 隐式的自动装配bean【…

2048天的创作旅程:坚持与成长

纪念成为创作者的2048天 一、引言二、坚持创作三、创作心情四、技术成长五、小结 &#x1f4a1;一个热爱分享高性能服务器后台开发知识的博主&#xff0c;目标是通过理论与代码实践的结合&#xff0c;让世界上看似难以掌握的技术变得易于理解与掌握。技能涵盖了多个领域&#x…

R语言使用installr包对R包进行整体迁移

今天分享一个R语言的实用小技巧&#xff0c;如果咱们重新安装了电脑&#xff08;我重装了电脑&#xff09;或者因为需要卸载旧版本的R软件&#xff0c;安装新版本的R&#xff0c;那么必然会造成R包的库缺失&#xff0c;需要重新下载&#xff0c;有些还不是官方的R包&#xff0c…

页缓存(PageCache)和预读机制(readahead )

页缓存&#xff08;PageCache)和预读机制&#xff08;readahead &#xff09; 页缓存&#xff08;PageCache)是操作系统&#xff08;OS&#xff09;对文件的缓存&#xff0c;用于加速对文件的读写。 page 是内存管理分配的基本单位&#xff0c; Page Cache 由多个 page 构成&…

linux项目部署 解决Nginx浏览器刷新出现404,但是不刷新是能够正常请求成功

文章目录 目录 文章目录 安装流程 小结 概要安装流程技术细节小结 概要 提示&#xff1a;部署成功&#xff0c;访问登录页面登录也成功&#xff0c;强制刷新浏览器报404问题 进入到系统 刷新页面 解决流程 参考如图&#xff0c;再下面添加这条配置信息 location / {try_file…

如何用好PMP项目管理知识

PMP(Project Management Professional&#xff0c;项目管理专业人士)是由国际项目管理协会&#xff08;PMI&#xff09;颁发的全球最高级别的项目管理认证&#xff0c;认证需要通过严格的考试&#xff0c;并具备相应的工作经验和教育背景。 作为一名咨询师&#xff0c;我们经常…

攻防世界08-backup

8-backup 网页添加后缀下载源文件 在链接后面追加index.php.bak,会出现软件下载&#xff0c;下载后&#xff0c;用记事本的方式打开 此时flag就出现了 kali扫描 当你不知道后缀是什么的时候&#xff0c;可以用kali进行扫描 记得更改源为国内的镜像源 vim /etc/apt/sources.…

配置linux的oracle 21c启停服务

一、配置启停 1、使用root用户登陆 su - root 2、修改oratab文件 修改oratab文件&#xff0c;将红框里面的N改为“Y”&#xff0c;使启停脚本能够生效 vi /etc/oratab 3、验证 配置好后就能够使用 dbshut 停止服务 和 dbstart 启动服务 了 2.1启动服务 su - oracle dbstart…

哈希函数的简单介绍

哈希函数&#xff1a; hash: 把....弄糟(乱) 又称为散列函数&#xff0c;杂凑函数 什么是哈希表&#xff1f; 哈希表简单来说可以看作是是对数组的升级&#xff0c;&#xff08;也有不少人认为哈希表的本质就是数组&#xff09;&#xff0c;那么哈希表和数组的具体联系和区…

4.Spring AOP

4.1 Spring AOP的基本概念 4.1.1 AOP的概念 在业务处理代码中&#xff0c;通常都有日志记录、性能统计、安全控制、事务处理、异常处理等操作。尽管使用OOP可以通过封装或继承的方式达到代码的重用&#xff0c;但仍然存在同样的代码分散到各个方法中。因此&#xff0c;采用OO…

Linux学习-数据库

数据库软件: 关系型数据库: Mysql Oracle SqlServer Sqlite 非关系型数据库&#xff1a; Redis NoSQL 1.数组、链表、文件、数据库 数组、链表: 内存存放数据的方式(代码运行结束、关机数据丢失) 文件、…

网络安全赛事中开源威胁情报的妙用

写在前面 近期参与了一场网络安全赛事&#xff0c;一些题目的解法涉及到开源网络威胁情报&#xff0c;遂对相关题目及涉及到的知识点进行分析。 什么是OSCTI 开源网络威胁情报 (Open-Source Cyber Threat Intelligence,OSCTI)是详细描述针对某个组织网络安全威胁的数据。OSC…

【go从入门到精通】探索延迟调用(defer)用法和陷阱

作者简介&#xff1a; 高科&#xff0c;先后在 IBM PlatformComputing从事网格计算&#xff0c;淘米网&#xff0c;网易从事游戏服务器开发&#xff0c;拥有丰富的C&#xff0c;go等语言开发经验&#xff0c;mysql&#xff0c;mongo&#xff0c;redis等数据库&#xff0c;设计模…

flink network buffer

Flink 的网络协议栈是组成 flink-runtime 模块的核心组件之一&#xff0c;是每个 Flink 作业的核心。它连接所有 TaskManager 的各个子任务(Subtask)&#xff0c;因此&#xff0c;对于 Flink 作业的性能包括吞吐与延迟都至关重要。与 TaskManager 和 JobManager 之间通过基于 A…

Linux标准c库操作(4.15)

fopen函数“const char *mode”参数选项。 结果&#xff1a; 标准库c写入结构体到文件&#xff1a; #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <string.h> #in…

如何在Vue3中使用H.265视频EasyPlayer.js流媒体播放器?

H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;可支持H.264与H.265编码格式&#xff0c;性能稳定、播放流畅&#xff0c;能支持WebSocket-FLV、HTTP-FLV&#xff0c;HLS&#xff08;m3u8&#…

Java | Leetcode Java题解之第28题找出字符串中第一个匹配项的下标

题目&#xff1a; 题解&#xff1a; class Solution {public int strStr(String haystack, String needle) {int n haystack.length(), m needle.length();if (m 0) {return 0;}int[] pi new int[m];for (int i 1, j 0; i < m; i) {while (j > 0 && needl…

Linux学习之路 -- 进程篇 -- PCB介绍 -- 进程的孤儿和僵尸状态

前面介绍了进程的各种状态&#xff0c;下面介绍比较特殊的两种状态 -- 孤儿和僵尸&#xff08;僵死&#xff09;。 一、僵尸状态 我们创建进程的目的其实就是想要进程帮我们执行一些任务&#xff0c;当任务被执行完后&#xff0c;进程的使命其实就已经完成了。此时我们就需要…

牛客Linux高并发服务器开发学习第一天

Linux开发环境搭建 安装Xshell 7远程连接虚拟机的Ubuntu 安装Xftp 7可以传输文件(暂时还没使用) 安装VMware Tools可以直接从Windows系统向虚拟机Linux系统拖拽文件实现文件交互。 安装CScode可以远程连接Linux系统进行代码的编写。&#xff08;Windows系统与Linxu系统公钥…

(十)C++自制植物大战僵尸游戏设置功能实现

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/m0EtD 游戏设置 游戏设置功能是一个允许玩家根据个人喜好和设备性能来调整游戏各项参数的重要工具。游戏设置功能是为了让玩家能够根据自己的需求和设备性能来调整游戏&#xff0c;以获得最佳的游戏体验。不同的游戏和平…