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

本文主要是介绍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;
}

 

这篇关于20240415,构造函数和析构函数,拷贝构造函数调用时机规则的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/909322

相关文章

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

MySQL字符串常用函数详解

《MySQL字符串常用函数详解》本文给大家介绍MySQL字符串常用函数,本文结合实例代码给大家介绍的非常详细,对大家学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql字符串常用函数一、获取二、大小写转换三、拼接四、截取五、比较、反转、替换六、去空白、填充MySQL字符串常用函数一、

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

PostgreSQL中rank()窗口函数实用指南与示例

《PostgreSQL中rank()窗口函数实用指南与示例》在数据分析和数据库管理中,经常需要对数据进行排名操作,PostgreSQL提供了强大的窗口函数rank(),可以方便地对结果集中的行进行排名... 目录一、rank()函数简介二、基础示例:部门内员工薪资排名示例数据排名查询三、高级应用示例1. 每

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字