当前位置: 首页 > news >正文

构造函数和析构函数

概念:对象的初始化和清理是非常重要的,一个对象在使用之前,需要进行初始化,使用完成后也需要及时清理数据,简单来说构造函数时用来初始化成员属性的,析构函数时用来清理数据的。

C++中利用构造函数和析构函数解决以上的问题,这两个函数由编译器自动调用,完成对象的初始化和清理工作,对象的初始化和清理是强制性的,如果我们不提供构造函数和析构函数,编译器会给我们提供,但是是空实现。

构造函数

概念:主要作用于创建对象时为成员属性赋值,构造函数由编译器自动调用,无需手动调用。

语法:类名(){}

构造函数名和类名相同,无需返回值,构造函数默认是无参构造,也可以有参数,称为有参构造,本质是函数的重载,程序在调用对象的时候,会自动调用构造,无需手动调用,且只调用一次,因为只需要初始化一次。

构造函数分类

按函数参数分为默认构造和有参构造,按照类型分为普通构造和拷贝构造。

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

 构造函数的调用

int main()
{//括号法调用Person p;//默认构造函数调用。需要注意的是调用默认构造函数不要在后面加括号,会被编译器认为是函数的声明。Person p2(10);//有参构造Person p3(p2);//拷贝构造函数调用,需要传入一个person类型的值//显示法调用Person p4 = Person(10);//有参构造,这里的Person(10)是匿名对象,当前行执行结束后,系统就会立即回收掉匿名对象Person p5 = Person(p4);//拷贝构造,需要注意不要用拷贝构造函数初始化匿名对象,例如Person(p4),编译器会认为是对象的声明//隐式转换法Person p6 = 10;//有参构造调用Person p7 = p6;//拷贝构造函数调用
}

 拷贝构造函数的调用时机

1.使用一个创建完毕的对象来初始化一个新的对象
//使用一个创建完毕的对象来初始化一个新的对象
class Person
{
public:int m_age;Person()//默认构造{}Person(int age)//有参构造{m_age = age;}Person(const Person& p)//拷贝构造{m_age = p.m_age;}~Person()//析构{}};
int main()
{Person p1(10);Person p2(p1);cout << "p2的年龄" << p2.m_age << endl;//输出为10,说明以及成功拷贝过来了
}
 2.值传递的方式给函数参数传值
void value(Person p)
{cout << p.m_age << endl;
}
int main()
{Person p(10);value(p);
}

 3.值方式返回局部对象

Person value2()
{Person p1;cout << (int*)&p1 << endl;return p1;
}
void test()
{Person p = value2();cout << (int*)&p << endl;
}
int main()
{test();}

构造函数的调用规则

系统会默认提供三个函数给一个类中,默认构造,拷贝构造(对属性进行值拷贝),默认析构。

如果用户定义有参构造,系统不会再提供默认无参构造,但还是会提供拷贝构造,如果用户定义了拷贝构造函数,c++不会再提供其他的构造函数。

#include<iostream>
using namespace std;
class Person
{
public:int m_age;Person()//默认构造{cout << "默认构造函数调用" << endl;}Person(int age)//有参构造{m_age = age;cout << "有参构造函数调用" << endl;}Person(const Person& p)//拷贝构造{m_age = p.m_age;cout << "拷贝构造函数调用" << endl;}~Person()//析构{cout << "析构函数调用" << endl;}
};int main()
{Person p;//如果写了有参构造,没有写默认构造,系统也不会再提供默认构造了,再调用默认构造函数,编译器会报错p.m_age = 18;Person p2(p);//如果不写拷贝构造函数,系统会进行值拷贝,如果写了拷贝构造函数,编译器就不再提供默认构造。cout << "p2的年龄" << p2.m_age << endl;
}

析构函数

概念:主要作用在于在对象销毁前系统自动调用,完成清理工作。

语法:~类名(){}

析构函数和构造函数一样,没有返回值函数名前加~,且函数名与类名相同,区别是析构函数不能有参数,不能发生重载,也是会自动调用的。

#include<iostream>
using namespace std;
class Person
{
public:Person()//默认构造函数{cout << "默认构造函数调用" << endl;}~Person()//析构函数{cout << "析构函数调用" << endl;}
};
int main()
{Person p;//栈区数据,销毁前会自动调用析构函数
}

此时构造函数和析构函数没有手动调用,系统会自动调用。

http://www.xdnf.cn/news/34651.html

相关文章:

  • 数据结构排序算法全解析:从基础原理到实战应用
  • LabVIEW 程序维护:为何选靠谱团队?
  • C# 变量||C# 常量
  • Linux教程-常用命令系列一
  • 定制一款国密浏览器(10):移植SM2算法前,解决错误码的定义问题
  • 如何实现一个MCP server呢?
  • 基于蚁群算法的柔性车间调度最优化设计
  • mysql的函数(第二期)
  • Linux下 文件的查找、复制、移动和解压缩
  • spring-batch批处理框架(1)
  • Qt项目——Tcp网络调试助手服务端与客户端
  • 时态--06--现在完成時
  • GPT-SoVITS 使用指南
  • 【概率论】条件期望
  • 【网络原理】UDP协议
  • 下采样(Downsampling)
  • stm32(gpio的四种输出)
  • c++:线程(std::thread)
  • java怎么找bug?Arthas原理与实战指南
  • opencv图像旋转(单点旋转的原理)
  • 中国AIOps行业分析
  • [dp19_01背包] 目标和 | 最后一块石头的重量 II
  • AUTOSAR图解==>AUTOSAR_SWS_IntrusionDetectionSystemManager
  • 652SJBH动漫网站Cosplay
  • 嵌入式芯片中的 低功耗模式 内容细讲
  • 【NLP 66、实践 ⑰ 基于Agent + Prompt Engineering文章阅读】
  • linux socket编程之udp(实现客户端和服务端消息的发送和接收)
  • Springboot+vue3开发项目——热点事件
  • [特殊字符] 高质量 Java 综合题 × 10(附应用场景 + 多知识点考核)
  • Spring Boot常用注解全解析:从入门到实战