前言:在日常生活中,我们用的电子产品基本都有出厂设置,方便我们使用。当我们不再使用,更或者拿它换剪刀换不锈钢盆时候,我们会把手机里的信息清空来保证我们的浏览器记录不会泄露,毕竟要留清白在人间。而在C++中,对象的初始化和清理也是两个非常重要的问题,因此有了构造函数和析构函数
一:使用构造函数和析构函数的目的是什么?
二、认识构造函数和析构函数
1.定义
2.语法格式
构造函数的语法
析构函数的语法
3.构造函数的分类
无参构造函数(默认构造函数):
有参构造函数
拷贝构造函数
4.三种调用方法
括号法
显示法
隐式转换法
5.构造函数调用规则
6.拷贝构造函数的调用时机
C++的面向对象来源与生活,每个对象也有初始设置 以及 对象销毁前的清理数据的设置(即对象的初始化和销毁),在C++里利用了构造函数和析构函数解决上述问题
从函数的角度讲其语法格式:即返回值类型,函数名,参数,函数使用方法
类名(){}
1.构造函数没有返回值,也不写void。
2.构造函数的函数名与类名相同;
3.构造函数可以写参数,因此可以发生重载(有参数就成为有参构造函数,后边介绍构造函数分类会讲到)
4.程序在调用对象时会自动调用构造,无需手动调用,且自动调用一次
~类名(){}
1.析构函数没有返回值,也不写void。
2.构造函数的函数名与类名相同,不过需在名称前加符号~
3.在参数这点,析构函数与构造函数不同,析构函数不可以有参数
4.程序在对象销毁前会自动调用析构,无需手动调用,且自动调用一次
总体就三类:默认构造函数,有参构造函数,拷贝构造函数
两种分类方式:
按参数分:有参构造函数(后两种)和无参构造函数(第一种)
按类型分:普通构造函数(前两种)和拷贝构造函数(第三种)
注意:1.如果我们不提供构造和构析,编译器会提供
2.编译器提供的构造函数和构析函数是空实现
空实现:如果定义函数时只给出一对花括号{}而不给出其局部变量和函数体语句,则称该函数为“空函数”。简单来说:啥也不是。
class Person
{
public:
Person()
{
cout << "无参构造函数的调用" << endl;
}
~Person()
{
cout << "构析函数的调用" << endl;
}
int age;
};
class Person
{
public:
Person(int a)
{
age = a;
cout << "有参构造函数" << endl;
}
~Person()
{
cout << "构析函数的调用" << endl;
}
int age;
};
class Person
{
public:
Person()
Person(const Person& p)
{
age = p.age;
cout << "拷贝构造函数的调用" << endl;
}
~Person()
{
cout << "构析函数的调用" << endl;
}
int age;
};
分别是括号法、显示法隐式转换法。
下面用这三种方法来调用三种已经讲过的三种构造函数
class Person
{
public:
Person()
{
cout << "无参构造函数的调用" << endl;
}
Person(int a)
{
age = a;
cout << "有参构造函数" << endl;
}
Person(const Person& p)
{
age = p.age;
cout << "拷贝构造函数的调用" << endl;
}
~Person()
{
cout << "构析函数的调用" << endl;
}
int age;
};
//括号法
void test01()
{
Person p;
Person p2(10);
Person p3(p2);
}
//显示法
void test01()
{
Person p1;
Person p2 = Person(10);
Person p3 = Person(p2);
}
//隐式转换法
void test01()
{
Person p4 = 10; //相当于Person p4 = Person(10);系统会自动给你转成显示法
Person p5 = p4;
}
1.使用括号法调用默认函数时,不可加(), 如Person p1();系统会以为你这是函数的一个声明,返回值为Person、名称为p1、无参数,不会认为你是在创建对象
2.当Person(10)放在等式左边时,为匿名对象。对于匿名对象,在当前行执行结束后系统立即回收匿名对象
3.不要利用拷贝构造函数初始化匿名对象:Person(p3);,编译器会认为Person (p3) == Person p3;这相当于你在实例化一个对象p3,若此时你上边已经有一个p3的话会重定义。
默认情况下:编译器至少给一个类添加四个函数:
1.默认构造函数(空实现)
2.默认析构函数(空实现)
3.默认拷贝构造函数
4.赋值运算符operator=,对属性进行值拷贝
非默认的调用规则:
如果用户定义有参构造函数,C++就不再提供默认无参构造,但是会提供默认拷贝构造
如果用户定义拷贝构造函数,C++就不会再提供其他构造函数
此处读者可把前边定义的三个构造函数,依照调用规则,删除一些并运行一下,看编译器在两种情况下提供的构造函数各自有哪些
1.使用一个已经创建完毕的对象来初始化一个新对象
//使用一个已经创建完毕的对象来初始化一个新对象;
void test01()
{
Person p1(20);//有参构造
Person p2(p1);//拷贝构造的使用
cout << "p1:" << p1.m_Age << endl;
cout << "p2:" << p2.m_Age << endl;
}
2.值传递的方式给函数参数传值
void doWork(Person p)
{
}
void test02()
{
Person p;
doWork(p);
}
3.以值方式返回局部对象
//dowork2中,返回值并不是p1,而是p1的一个拷贝值
//我们可以输出p和p1的地址,会发现两个地址不同
Person doWork2() {
Person p1;
cout << (int*)&p1 << endl;
return p1;
}
void test03() {
Person p = doWork2();
cout << (int*)&p<< endl;
}
以上就是今天要讲的内容,本文介绍了构造函数和析构函数的相关知识点
如果帮到了你,可以点一个关注,后续学习笔记将每日更新哦。
也可以留下一个赞,你的赞是笔者更新的动力
如果文章有用的话,也可以收藏起来,代表自己学习过的痕迹,这块知识点遗忘时候可以方便查看