C++ 构造函数与析构函数

news2024/11/15 20:54:41

1.构造函数的引出
一个实实在在的对象,应该有合法的属性,而不是在对象出来之后,再去设置属性,要实现这个过程,必须在对象出来的这一时刻初始化合法的值,而且不能由程序员调用,要给属性合法的值,必须通过成员函数初始化,那么这个成员函数就应该比较特殊,特殊在能在对象出来的时刻自动调用,这个成员函数的作用是不但要给当前的对象开辟空间,而且还要给这个对象一个合法的值,它的功能就是把这个对象构造出来,所以我们把这样的函数称为构造函数。
【注意】
如果一个类中没有写构造函数,那么这个类中也有构造函数,因为如果没有构造函数的话数据成员就没有空间,只是这个构造函数没有合法的值,只分配空间。
2.构造函数的定义
构造函数是特殊的公有成员函数(在特殊用途中构造函数的访问限定可以定义成私有保护)。
数据成员多为私有的,要对它们进行初始化,必须用一个公有函数来进行。同时这个函数应该在且仅在定义对象时自动执行一次,称为构造函数。
3.默认构造函数
如果程序员没有写构造函数,则系统会提供一个默认的构造函数,默认构造函数的函数名和类名相同,无参,只是给里面的数据成员分配空间;如果程序员写了构造函数,则系统不会再提供默认构造函数。
4.构造函数的基本特点
函数名和类名相同,无返回类型,可以带参(可以重载),在对象出来的那一时刻自动调用。
主要代码:

class Table   //定义一个桌子类
{
public:
    // Table() { cout << "Table" << endl; } 
    Table(int l = 120, int w = 50, int h = 80)   //带默认值的构造函数,省去了写好几个构造函数
    {
        m_length = l;   //桌子长度
        m_width = w;    //桌子宽度
        m_height = h;   //桌子宽度
    }
    void Show()
    {
        cout << m_length << " " << m_width << " " << m_height << endl;
    }
private:
    int m_length;
    int m_width;
    int m_height;
};

void main()
{
    Table t;  //定义对象t,要自动调用构造函数,如果无参,不能写()
    //Table b();  错误,定义对象时如果无参不能写(),因为如果写了(),就相当于声明了一个函数叫b,返回值为Table
    t.Show();
    Table t1(60, 40);
    t1.Show();
    Table t2(120, 60, 40);
    t2.Show();
}

运行结果:
请添加图片描述
5.构造函数的作用
(1)创建对象
(2)初始化对象中的数据成员
(3)类型转换
6.构造函数作为类型转换
构造函数除了能构造对象,还能作为类型转换,将一个基本数据类型转换为对象,直接赋值给对象。但是当前构造函数必须带有基本数据类型的参数,才能做相应的转换,也就是说把一个基本数据类型的数据赋给一个类型,相应构造函数必须要有相应的基本数据类型作为参数。

class A
{
public:
    A() { cout << "A" << endl; }   //一个无参的构造函数,写了无参的构造函数,其他构造函数就不可以带默认值,也就是说不能再有带默认值的构造函数
    explicit A(int i)  //explicit是明确的,确定的意思,加上它之后说明当前的构造函数只能作为构造函数去创建对象
    {
        m_i = i;
        cout << "A(int)" << endl;
    }
private:
    int m_i;
};
void main()
{
    //A a = 10;       //要这么写的话,就不能写explicit关键字
                      /*把一个整型赋给一个类型,相应构造函数必须要有整型作为参数,
                      它相当于A b = A(10);其实是生成一个无名对象A ,用无名对象去构造当前的a,
                      编译器会自动优化就可以直接写为A b = 10;*/
    A a;    //调用无参的构造函数
    A b(10);   //调用带参数的构造函数

}

【注意】
①如果写了一个无参的构造函数,那么不能在写带有默认值的构造函数。
②explicit是明确的,确定的意思,在构造函数的前面加上它,就说明当前的构造函数只能作为构造函数去创建对象。
③把一个整型赋给一个类型,相应构造函数必须要有整型作为参数
7.构造函数的特征
(1)函数名与类名相同
(2)构造函数无函数返回类型说明。注意是没有函数返回类型而不是void,即什么也不写,不可以写void。实际上构造函数有返回值,返回的就是构造函数所创建的对象。
(3)在程序运行时,当新的对象被建立,该对象所属的类的构造函数自动被调用,在该对象生存期中也只调用这一次。
(4)构造函数可以重载。严格地讲,类中可以定义多个构造函数,它们由不同的参数表区分,系统在自动调用时按一般函数重载的规则选一个执行。
(5)构造函数可以在类中定义,也可以在类中声明,在类外定义。
(6)如果类说明中,没有给出构造函数,则C++编译器自动给出一个缺省的构造函数:类名(void){ }
但是只要我们定义了一个构造函数,系统就不会自动生成缺省的构造函数。只要构造函数是无参的或者只要各参数均有缺省值的,C++编译器都认为是缺省的构造函数,并且缺省的构造函数只能有一个。
8.构造函数的执行顺序
(1)遇到对象,自动调用当前类的构造函数
(2)传参
(3)根据数据成员在类里面的声明顺序,用冒号语法后面的值进行初始化
冒号语法就是成员初始化列表,成员初始化列表只能在构造函数里面写。
(4)进入构造函数函数体,执行其他操作

class A
{
public:
	A(int i = 0):m_i(i) { cout << "A" << m_i << endl; }
private:
	int m_i;
};
class B
{
public:
	B(int j = 10):a(j) 
	{
		cout << "B" << j << endl; 
	}
private:
	A a;
};
void main()
{
	B b(20);
}

【运行结果】
请添加图片描述
【说明】
从当前的主函数开始,第一步遇到一个对象b,要自动调用当前B类的构造函数;第二步传参,把20传给了j;第三步,根据数据成员在类里面的声明顺序,数据成员只有a,用冒号语法后面的值进行初始化,用j去初始化当前的数据成员a,发现数据成员a是一个对象,然后调用A类的构造函数,把j传给了i,再根据数据成员在类里面的声明顺序,数据成员只有m_i,用冒号语法后面i的值去给m_i去初始化,m_i就初始化完了,m_i初始化为20;第四步,进入到A类的构造函数函数体执行代码,输出A20,此时给A的构造函数就结束了,就去执行B的构造函数函数体,执行代码,输出B20。

class A
{
public:
	A(int i = 0, int j = 0) :m_j(j), m_i(m_j)
	{
		cout << m_i << " " << m_j << endl;
	}
private:
	int m_i;
	int m_j;
};
void main()
{
	A a(10, 30);
}

【运行结果】
请添加图片描述
【说明】
从当前的主函数开始,第一步遇到一个对象a,自动调用当前构造函数A;第二步传参,把10传给了i,把30传给了j,第三步,根据数据成员在类里面的声明顺序m_i,m_j,依次给m_i,m_j初始化,用冒号语法后面的m_j给m_i初始化,因为m_j没有值是随机值,所以m_i初始化为随机值,再用冒号语法后面的j给m_j初始化,m_j初始化为30;第四步,进入到构造函数A的函数体执行代码,输出m_i,m_j的值。
9.析构函数的引出
我们在构造类的时候要给类里面的数据成员开辟内存空间,当对象的生命周期结束之后要消失,这个空间就需要被释放掉,在释放内存空间的时候就要用到析构函数。
10.析构函数的定义
当定义一个对象时,C++自动调用构造函数建立该对象并进行初始化,那么当一个对象的生命周期结束时,C++也会自动调用一个函数注销该对象进行善后工作,这个特殊的成员函数就叫做析构函数。
11.析构函数的特征
(1)析构函数名与类名相同,但在前面加上字符’~',如~CGoods();
(2)析构函数无函数返回类型,在这方面与构造函数是一样的。但是析构函数不带任何参数。
(3)一个类有一个且只有一个析构函数,这与构造函数不同。
(4)对象注销时,系统自动调用析构函数。
(5)如果类说明中没有给出析构函数,则C++编译器会自动给出一个缺省的析构函数。

class A
{
public:
    A(int i = 0) :m_i(i) { cout << "A" << m_i << endl; }
    ~A() { cout << "~A" << m_i << endl; }
private:
    int m_i;
};
void fn()
{
    A c(40);
}
void test()
{
    static A d(50);
}
void main()
{
    A a(20); 
    A b(30);  
    fn();  
    test();  
    test();
    test();
}

【运行结果】
请添加图片描述
【分析】
(1)先构造的后析构。
(2)在主函数结束之前,当作用域即将要消失的时候调用析构函数。
(3)fn()函数中的对象c,c的作用域是在进入fn()函数的时候构造,出了fn函数c的作用域就要消失,就要调用析构函数。
(4)test()函数中的d是一个静态变量,在第一次遇到静态变量的时候给它开辟空间,后面不再开辟空间,出了test()函数之后它的空间不消失,但是它的空间外界不能用,它空间里面的值就一直保存着。所以主函数中第二次遇到test()函数的时候就不再构造了,因为它的空间并没有消失,不需要重新开辟空间。静态空间的作用域在程序都执行完之后才消失。

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

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

相关文章

熟悉requests用法,实现简单网站爬虫

本文模拟的是前后端分离项目&#xff0c;使用账号密码登录获取到token&#xff0c;拿着token加载用户信息&#xff0c;加载分页列表数据并存储文件。 本文用到的知识点&#xff1a; 1、urllib.parse URL解析&#xff1b; 2、session用法&#xff0c;保存所有请求在一个会话中&a…

muduo源码剖析--Buffer

Buffer类 Buffer类是自定义处理数据输入缓冲的类&#xff0c;底层是vector< char >&#xff0c;通过readIdx和writeIdx将缓冲区分为3个部分&#xff0c;第一部分是预留的8字节已经读出的缓冲区字节数、第二部分是还未读出的部分、第三部分是可写的部分。 Buffer类的设计…

JavaScript【三】JavaScript中的数组

文章目录&#x1f31f;前言&#x1f31f;数组&#x1f31f;声明&#xff1a;&#x1f31f; 隐式创建&#xff1a;&#x1f31f; 实例化构造函数&#xff1a;&#x1f31f; 注意&#xff1a;一个值为数组的长度。&#x1f31f; 访问&#xff1a;&#x1f31f; 遍历&#xff1a;&…

C++练级之初级:第三篇

C练级之初级&#xff1a;第三篇 1.探索C中函数重载的本质 &#x1f914;首先我们先解决一下为什么C支持函数重载&#xff0c;而C语言不支持&#xff1f; 这里就不得不提起编译链接了&#x1f601;&#xff1b; &#x1f449;这是编译链接篇 以这三个简单的文件为例&#xff1…

C51单片机串口通信(概念部分)

1.通信的基本概念 1.1&#xff1a;串行通信与并行通信 &#xff08;1&#xff09;.串行通信 串行通信是指用一根数据线将 一个字节的八个bit位连接&#xff0c;从低位开始依次传输。 优点&#xff1a;成本便宜&#xff0c;传输稳定 缺点&#xff1a;速度慢 并行通信是指将一…

重学Java设计模式-行为型模式-责任链模式

重学Java设计模式-行为型模式-责任链模式 内容摘自&#xff1a;https://bugstack.cn/md/develop/design-pattern/2020-06-18-重学 Java 设计模式《实战责任链模式》.html#重学-java-设计模式-实战责任链模式「模拟618电商大促期间-项目上线流程多级负责人审批场景」 责任链模…

stegano(图片隐写、摩斯密码)

附件是PDF&#xff0c;我们在选择内容时发现光标溢出了文本 说明这里还存在一些我们看不到的内容 直接CtrlA全选&#xff0c;CtrlC复制后新建一个纯文本文件 将复制的东西粘贴过去 粘贴后发现果然多出来了一些东西&#xff0c;提取出来 BABA BBB BA BBA ABA AB B AAB ABAA A…

3.2 三角分解法

思维导图&#xff1a; 3.2 矩阵的三角分解 3.2.1 什么是矩阵的三角分解&#xff1a; 矩阵的三角分解&#xff0c;也称为LU分解&#xff0c;是一种将一个矩阵分解为一个下三角矩阵和一个上三角矩阵的方法。该分解通常用于解线性方程组和计算矩阵的行列式和逆矩阵。 设A为n*n的…

【通世智库】宁晓红:医疗更完整的样子

2022年的10月&#xff0c;北京协和医院缓和医学中心成立了&#xff0c;这是巨大的好消息&#xff01;北京协和医院连续13年蝉联中国医院排行榜榜首&#xff0c;它率先成立了缓和医学中心&#xff0c;可见缓和医疗在医学领域的重要地位和不可估量的价值。【作者&#xff1a;宁晓…

软件安全之CRC检测

CRC介绍 在玩某些游戏&#xff0c;例如fps类游戏时&#xff0c;你想要修改某些特定的数值实现一些功能&#xff0c;这时你很有可能会被查封账号甚至禁封机器码。因为你更改了游戏中的数据&#xff0c;从而导致接收方收到”错误的数据“。为尽量提高接收方收到数据的正确率&…

可视化Echarts中title、tooltip、legend的常用属性设置

title中常用的设置 配置项--tooltip 配置项--legend title中常用的设置 title 标题组件&#xff0c;包含主标题和副标题。 以下是常用的对标题的设置 title:{//设置图表的标题text:"主标题",link:"baidu.com", //设置标题超链接target:"self&q…

2023最新谷粒商城笔记之支付服务篇(全文总共13万字,超详细)

支付服务 这里我们是使用的支付宝进行支付&#xff0c;所以需要调用支付宝的相关API&#xff0c;下面来了解一下怎样使用支付宝进行线上支付。 支付宝配置相关概念 支付宝开放平台传送门&#xff1a;支付宝开放平台 网站支付DEMO传送门&#xff1a;手机网站支付 DEMO &…

数字滤波器设计——IIR 滤波器

数字滤波器设计实践介绍 此示例说明如何使用 Signal Processing Toolbox 产品中的 designfilt 函数&#xff0c;根据频率响应设定设计 FIR 和 IIR 滤波器。该示例重点讲述低通滤波器&#xff0c;但大多数结果也适用于其他响应类型。 此示例主要介绍数字滤波器的设计&#xff…

D3.js实现线条的流动效果(从一端移动到另一端并且变色)

参考&#xff1a; SVG&#xff1a;理解stroke-dasharray和stroke-dashoffset属性 使用SVG CSS实现动态霓虹灯文字效果 纯CSS实现帅气的SVG路径描边动画效果 实现的效果为&#xff1a;路径左移到完全看不见的地方&#xff0c;然后一边右移&#xff0c;一边从黑色变为红色 <…

社科院与杜兰大学金融管理硕士项目—人生的每一条路都可以看作是正确的路

成年人的世界里没有什么是容易的。生活中经常听到人说&#xff1a;早知道现在过得这么辛苦&#xff0c;当年真应该好好读书&#xff1b;早知道这个行业这么难出头&#xff0c;当年真不应该踏入这一行&#xff1b;早知道爱人这么不靠谱&#xff0c;当年不跟他结婚就好了……有时…

系统集成项目管理工程师软考知识点(每天更新)

第一章指路&#xff1a;系统集成项目管理工程师软考知识点&#xff08;第一章已完结&#xff09;_程序猿幼苗的博客-CSDN博客 第二章指路&#xff1a;系统集成项目管理工程师软考知识点&#xff08;第二章已完结&#xff09;_程序猿幼苗的博客-CSDN博客 本专栏将会更新完整~ …

【DRF开发手册】使用 Django Rest Framework 的 @action 定义自定义方法

本文节选自笔者博客&#xff1a; https://www.blog.zeeland.cn/archives/so3f209hfeac &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是Zeeland&#xff0c;全栈领域优质创作者。&#x1f4dd; CSDN主页&#xff1a;Zeeland&#x1f525;&#x1f4e3; 我的博客&…

C++ Primer Plus(第6版) 全书重点学习笔记

目录 第10章 对象和类 10.1 过程性编程和面向对象编程 10.2 抽象和类 10.2.1 类简介 10.2.2 实现类成员函数 10.3 类的构造函数和析构函数 10.3.1 声明和定义构造函数 10.3.2 使用构造函数 10.3.3 默认构造函数 10.3.4 析构函数 10.4 this指针 10.5 对象数组 10.6 …

[长安杯 2021学生组]baigei

Index 前言介绍漏洞 利用思路利用过程一.编写交互函数二.填充Tcache Bin三.释放Tcache Bin四.获取Libc地址五.Tcache Bin Attack六.完整EXP&#xff1a; 前言 最近有点迷茫&#xff0c;开始放松自己了。 心态还不是很对&#xff0c;需要继续调整。 介绍 本题是一题经典的堆题…

Java学习笔记:内部类,静态内部类,匿名内部类

​这是本人学习的总结&#xff0c;主要学习资料如下 疯狂Java讲义第三版&#xff0c;李刚编&#xff0c;电子工业出版社出版 目录 1、内部类1.1、内部类简介1.2、内部类与外部类的关系和区别&#xff1a;1.3、内部类的语法 2、 非静态内部类3、静态内部类4、匿名内部类 1、内部…