构造函数与析构函数

这篇具有很好参考价值的文章主要介绍了构造函数与析构函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在上一篇内容中,自定义的类里面是存在成员函数的;而这些成员函数都是我们显式定义出来的,而一般情况下,类中还存在几个默认的成员函数:构造函数、析构函数、拷贝构造函数、赋值重载以及取地址重载等,而本节则主要论述前两个函数,构造函数和析构函数!

关于类和对象这部分内容,是有些晦涩的,不易理解的,主要是其中要点过于琐碎,还是应该回归于书本!
构造函数与析构函数

1.构造函数

在之前我们都是利用Init函数对对象中的数据进行初始化的,而C++中提供了一种较为高效的初始化方式——构造函数。

需要注意的是,构造函数的主要任务是对对象的数据进行初始化操作!

1.1构造函数特征

1️⃣构造函数的引入

构造函数的名字必须与类名一致,且不能任意命名,以便编译系统识别,且构造函数不具有任何类型不具有返回值!

下面给出一个例子:

class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	void Display();
};
void Date :: Display()
{
	cout << _year << ":" << _month << ":" << _day << endl;
}
int main()
{
	Date d1;
	d1.Display();
	return 0;
}

其中Date就是一个简易的构造函数!因此对象d1就的数据就被初始化成了1:1:1!
构造函数与析构函数
在上述调用过程中,存在以下几点需要注意:

1.在建立类的对象时,类的构造函数会自动调用。在建立对象时系统会为该对象分配存储单元,此时先执行构造函数,就把指定的初值送到有关的数据成员的存储单元中去了。

2.构造函数没有返回值,不需要类型,是定义对象时自动调用不需要人为手动调用!

3.如果用户未定义构造函数,则C++系统会为其生成一个构造函数,只是这个构造函数是空的,也没有参数!

关于第3点,我们不妨将先前的构造函数注释掉,此时则可以很好的观察出这一特性!
构造函数与析构函数

所以当我们没有显式定义构造函数的时候,编译器会自动生成1个无参的默认构造函数,显式定义的话,编译器就不再生成了!

2️⃣带参数的构造函数

Date(int year,int month,int day)
{
	_year = year;
	_month = month;
	_day = day;
}

将构造函数改成这个样子,此时在使用该类去定义对象的时候就需要传递参数了!

int main()
{
	Date d1(2022, 10, 4);
	d1.Display();
	return 0;
}

如果我们将该构造函数改为缺省参数的话,此时传几个参数我们就可以自己决定了,既可以全传也可以不穿,或者传递部分参数。

以下我写一个全缺省的参数的构造函数:

Date(int year=1,int month=1,int day=1)
{
	_year = year;
	_month = month;
	_day = day;
}

3️⃣构造函数的重载

构造函数支持重载!

我们知道,函数重载需要保证函数名一致,但是函数的参数类型顺序都要存在差异才可以算的上是函数重载,因为此条性质比较简单,就不进行演示了!

class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	Date(int year=1,int month=1,int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Display();
};

此时这种重载是不正确的,编译器会报错,因为当定义对象自动调用构造函数时,编译器并不知道调用哪一个构造函数!因此就存在了二义性!

Box(int a=10,int b=10,int c=10);
Box();
Box(int a,int b);

//.......
当存在以下调用时:
Box box1;
//此时是调用第一个函数还是第二个呢?
Box box2(10,20);
//此时调用第一个函数还是第三个呢?

所以存在默认参数的构造函数时需要注意调用传参时是否存在错误!

4️⃣默认构造函数

默认构造函数:在建立对象的时候不必给出实参的构造函数都被称为默认构造函数!

因此,有了上述概念,我们重新观察日期类:

class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	Date(int year=1,int month=1,int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Display();
};

前面提到过,当我们未显式定义构造函数的时候,此时编译器会给我们提供一个构造函数,这个构造函数也被称为默认构造函数,这种构造函数的函数体是空的,参数也没有;所以用户在创建对象的时候如果需要数据成员存在初值,就必须自己定义构造函数!

所以上述代码中两个构造函数都属于默认构造函数!

而一个类中只能存在一个构造函数!

2.析构函数

2.1析构函数的引入

析构函数:是一个特殊的成员函数,他的作用与构造函数相反,它的命名前需要加上“~”,也是没有返回值与类型的!

析构函数的主要作用并不是删除对象,而是在撤销对象占用的内存之前完成的一些清理工作,也就是说当对象要被销毁时或者生命周期结束时会自动调用析构函数!析构函数在一定程度上与构造函数一致,同样是没有函数类型、没有返回值,并且最重要的是没有函数参数的!

class Test
{
private:
	int* arr;
	int num;
public:
	Test(int n);
	void Display(int n);
	~Test();
};

Test::Test(int n)
{
	arr = (int*)calloc(n,sizeof(int));
	if (arr == NULL)
	{
		perror("malloc fail");
		return;
	}
	num = 100;
}
Test::~Test()
{
	free(arr);
	num = 0;
}
void Test::Display(int n)
{
	for (int i = 0; i < n; i++)
	{
		cout << arr[i] << "  ";
	}
	cout << endl;
}
int main()
{
	Test t1(10);
	t1.Display(10);

}

测试以上代码,可以得出以下结论:

  1. 由于析构函数没有参数所以不能重载只能存在1个
  2. 析构函数在没有显式定义的时候,编译器会自动生成1个析构函数,但它只是虚有其表只是有虚构函数的名称与形式,实际上什么操作都不会进行!
  3. 自定义类型会调用它的析构函数
  4. 当然,有些类是需要析构函数的,但是有些类是不需要析构函数的,所以当存在资源申请的时候就需要写析构函数,否则会造成资源泄漏!

2.2析构函数的调用情况

  1. 如果一个函数定义了一个对象(局部对象),当这个函数调用结束时,对象应该被释放,在对象释放前会自动执行析构函数!
  2. 静态(static)局部对象在函数调用结束对象并不会被释放,当main函数结束或者调用exit函数结束程序时,会调用析构函数!
  3. 如果定义了一个全局的变量,则在程序的流程离开其作用域时,调用该全局对象的析构函数!
  4. 当用new建立对象时,当用delete运算符释放该对象时先调用析构函数!

3.析构函数与构造函数的调用顺序

3.1构造函数与析构函数特性补充

  1. 构造函数中对于内置类型是不做处理的,对于自定义类型会调用其构造函数!
  2. 对于析构函数对于内置类型在销毁时系统会自动回收内存,而对于自定义类型会调用其析构函数!

3.2二者调用顺序

先构造的后析构,后构造的先析构

构造函数与析构函数

class Time
{
public:
	Time()
	{
		cout << "Time()" << endl;
	}
	~Time()
	{
		cout << "~Time()" << endl;
		_hour = 0;
		_minute = 0;
		_second = 0;
	}
private:
	int _hour;
	int _minute;
	int _second;
};

class Date
{
private:
	// 基本类型(内置类型)
	int _year = 1970;
	int _month = 1;
	int _day = 1;
	// 自定义类型
	Time _t;
};
int main()
{
	Date d1;
	Date d2;
	return 0;
}

调试这个程序就可以很轻易的看出这一特性!而这一特性也完全与栈的原理一样!

注:

  • 如果在全局范围定义对象,那么它的构造函数在本文件模块中的所有函数执行之前调用,如果一个程序包含多个文件,那么它的构造函数的调用顺序是不确定的,当main函数结束或者调用exit结束程序时,调用析构函数!
  • 如果定义局部对象,那么定义时自动调用构造函数,函数调用结束时,调用析构函数!
  • 如果定义静态函数,则只在程序调用的第一次调用构造函数,当main函数结束时或者调用exit函数时调用析构函数!

Ending

关于构造函数和析构函数也就结束了,而构造函数中还有一种特殊的构造函数,叫做拷贝构造函数,这个在下一篇博客中会介绍!🙋‍♂️
构造函数与析构函数文章来源地址https://www.toymoban.com/news/detail-473430.html

到了这里,关于构造函数与析构函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [C++]构造与毁灭:深入探讨C++中四种构造函数与析构函数

     个人主页:北·海  🎐CSDN新晋作者  🎉欢迎 👍点赞✍评论⭐收藏 ✨收录专栏:C/C++ 🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!🤗 目录 构造函数有什么作用? 构造函数有什么特点 构造函数的种类 一.默认构造函数 1.什么是

    2024年02月09日
    浏览(31)
  • <c++> 类的继承 | 基类与派生类 | 构造函数与析构函数

    🚀 个人简介:CSDN「 博客新星 」TOP 10 , C/C++ 领域新星创作者 💟 作    者: 锡兰_CC ❣️ 📝 专    栏: 从零开始的 c++ 之旅 🌈 若有帮助,还请 关注➕点赞➕收藏 ,不行的话我再努努力💪💪💪 c++ 面向对象三大特性: 封装,继承,多态 。通过本文我们将了解什么是类的

    2023年04月20日
    浏览(38)
  • Roscpp中构造函数与析构函数及在无人机串口通信应用

    构造函数 作用:初始化,在创建对象时会自动调用,有点像Python中的 __init__ 方法 特点:命名为 class命名 ,在public中声明。 析构函数 作用:完成释放前的一些清理工作。 特点:命名为 ~+class命名 ,在public中声明。 调用顺序 栈的顺序,先构造的后析构。 ROScpp中在include文件

    2024年01月21日
    浏览(34)
  • 【C++初阶】类和对象——构造函数&&析构函数&&拷贝构造函数

    ========================================================================= 个人主页点击直达: 小白不是程序媛 C++系列专栏: C++头疼记 ========================================================================= 目录 前言 类的6个默认成员函数 构造函数 概念 构造函数的特性 析构函数 概念 析构函数特性 拷贝构

    2024年02月06日
    浏览(41)
  • C++ 类和对象(二)构造函数、析构函数、拷贝构造函数

            本文将介绍类的6个默认成员函数中的构造函数、析构函数和拷贝构造函数,赋值重载和取地址重载涉及运算符重载的知识,将在下篇讲解。所谓默认成员函数,也就是每个类都有的成员函数,我们可以显式定义这些函数,否则,编译器会自动生成它们。 目录 前言

    2024年02月09日
    浏览(35)
  • C++ 类构造函数 & 析构函数

    类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。 下面的实例有助于更好地理解构造函数的概念: 当上面的代码

    2024年01月17日
    浏览(40)
  • 【C++】类与对象(构造函数、析构函数、拷贝构造函数、常引用)

       🌈个人主页: 秦jh__https://blog.csdn.net/qinjh_?spm=1010.2135.3001.5343 🔥 系列专栏:   目录 类的6个默认成员函数 构造函数 特性  析构函数 特性  析构的顺序 拷贝构造函数 特性 常引用      💬 hello! 各位铁子们大家好哇。              今日更新了类与对象的构造函数、

    2024年02月21日
    浏览(35)
  • C++:构造方法(函数);拷贝(复制)构造函数:浅拷贝、深拷贝;析构函数。

    1.构造方法(函数) 构造方法是一种特殊的成员方法,与其他成员方法不同: 构造方法的名字必须与类名相同; 无类型、可有参数、可重载 会自动生成,可自定义 一般形式:类名(形参); 例: Stu(int age); 当用户没自定义构造方法时,系统将会执行默认构造方法,当用户自定义一个

    2024年02月11日
    浏览(34)
  • ⚡【C++要笑着学】(7) 默认成员函数:构造函数 | 析构函数 | 拷贝构造函数

    🔥 订阅量破千的火热 C++ 教程 👉 火速订阅 《C++要笑着学》   🔥 CSDN 累计订阅量破千的火爆 C/C++ 教程的 2023 重制版,C 语言入门到实践的精品级趣味教程。 了解更多: 👉  \\\"不太正经\\\" 的专栏介绍  ← 试读第一章 订阅链接: 🔗 《C语言趣味教程》 ← 猛戳订阅!   本篇

    2024年02月07日
    浏览(55)
  • 类的构造函数和析构函数

    构造函数是类的入口函数 析构函数是类的销毁函数 a、构造函数默认是public类型的,如果定义private则定义外部不能进行对象的创建,所以只能是公有函数 b、构造函数是入口函数,所以可以进行参数的初始化,可以对部分或全部的函数进行初始化操作 c、构造函数是可以有多

    2024年01月20日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包