C++ 构造函数 与 析构函数
在我们C++类中,默认会有6个默认的成员函数,即使我们不写,也至少会有6个成员函数,分别是:构造函数、析构函数、拷贝构造、赋值操作符重载、取地址操作符重载、const修饰的取地址操作符重载。
构造函数
构造函数的功能就是给实例化出来的对象初始化。相当于在对象在被实例化的同时赋予初始值。类也是一种类型,是我们自定义的类型,那我们想要让我们自定义的类型像内置类型一样使用,就肯定离不来我们的默认的成员函数。
对于内置类型,可以在定义时初始化int num = 5
,定义变量num并初始化num为5。那我们的自定义类型也可以,那就要用到我们的构造函数。在我们实例化一个对象时,编译器也会自动调用了我们的默认无参构造函数。
class Date
{public: void SetDate(int year, int month, int day){_year = year;_month = month;_day = day;}void Display(){cout << _year << "-" << _month << "-" << _day << endl;}
private: int _year; int _month;int _day;
};int main()
{ Date d;//调用了默认的无参构造函数return 0;
}
一个对象的构造函数只能被调用一次,且不能显示调用,也就是说不能通过对象去调用构造函数。
构造函数格式:类名 (参数)
构造函数时可以重载的,当我们自己写了构造函数,编译器就不会帮我们生成一个构造函数。构造函数分为无参构造和有参构造。无参构造和编译器生成的默认构造函数时一样的。由于无参的构造函数并不能很好的初始化对象,所以我们通常写的是有参的构造函数。
//无参的构造函数
Date()
{}
//有参的构造函数
Date(int year, int month, int day)
{_year = year;_month = month;_day = day;
}
我们在创建对象的时候就可以给对象赋初始值:
Date d1; //调用无参构造
Date d2(2021, 2, 3); //调用有参构造
下面我们来测试:
在主函数中创建对象
class Date
{public: //无参的构造函数Date(){cout << "Date()" << endl;}//有参的构造函数Date(int year, int month, int day){_year = year;_month = month;_day = day;cout << "Date(int, int,int)" << endl;}void Display(){cout << _year << "-" << _month << "-" << _day << endl;}
private: int _year; int _month;int _day;
};
int main()
{Date d1; d1.Display();Date d2(2021, 2, 3);d2.Display();return 0;
}
从运行结果可以证明,d1调用了无参构造,d2调用了有参构造。但是我们发现d1对象中的成员都是随机值。为什么会是随机值呢?我们的构造函数对内置类型的成员变量不会处理。那不给成员变量赋初值,那无参构造函数不是就没用了吗?当然不是 ,如果我们类的成员变量中,有自定义类型的成员变量,构造函数会去调用我们自定义类型的默认构造函数,如果没有默认构造函数,编译器就会报错。默认构造函数和构造函数时有区别的,下面会讲到。
注意:以下代码并不是创建对象
//不是创建对象,而是声明了一个函数
//函数名为 d,返回类型为Date类型,参数为空的函数。
Date d();
构造函数中还有一个定义是默认构造函数,默认构造函数就是不用传参数也可以创建对象,默认构造函数有,1、我们自己不写,编译器自动生成的无参构造函数。2、我们自己写了一个无参构造函数。3、在有参构造函数中给形参缺省值(常用常写)
有参带缺省值的默认构造函数:
Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;cout << "Date(int, int,int)" << endl;}
总结起来就是,可以不传参数创建对象的类是具有默认构造函数的。但是注意,默认构造函数在一个类中只能出现一个。
总结:
0、一个对象只能调用一次构造函数。
1、构造函数是对象创建的时候编译器会自动调用的默认成员函数。完成的任务是对对象的初始化,非创建对象。
2、构造函数可以重载,分为有参构造和无参构造
3、如果我们没有写构造函数,编译器会自动生成一个无参的构造函数
4、无参的构造函数和全缺省的构造函数都称为默认构造函数,且他们中只能存在一个。
5、无参构造函数只会对自定义类型做初始化,内置类型不做初始化。
6、当成员变量有自定义类型的变量时,所有的构造函数都会自定调用自定义类型的默认构造函数,必须是默认构造函数,如果没有,编译器会报错。
析构函数
析构函数和构造函数的功能类似,析构函数是当一个对象要被销毁时会被调用自身的析构函数,完成类的一些资源清理工作。
析构函数格式:~类名()
析构函数的特点:
1、无参数无返回值
2、一个类只能有一个析构函数,如果没有显示定义,编译器会自动生成一个析构函数。
3、对象生命周期结束编译器会自动调用析构函数
例如在我们的数据结构中,常常会用到一些结构,像栈这种需要结束时释放掉之前malloc开辟的空间,如果不释放就会造成内存泄漏。而在C++中,我们可以将栈的销毁写在析构函数中,这样子就不会忘记调用销毁的函数了。编译器就可以自动调用析构函数完后资源的清理了。
//析构函数
~Stack()
{if (_sData){free(_sData);_sData = NULL;_top = 0;_capacity = 0;}
}
但是如果没有涉及到的内存开辟,或者需要释放的类,可以不用写析构函数,使用编译器自动生成的析构函数就可以。自动生成的析构函数有没有作用呢?答案是有的,即使自身没有资源要清理,当存在自定义类型的变量,且该变量需要释放空间。这时候编译器生成的析构函数会自动调用该自定义类型的变量的析构函数。完成释放清理资源的功能。
析构的顺序是后创建的对象先析构
class Date
{public: Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;cout << _year << "Date()" << endl;}~Date(){cout << _year << "~Date()" << endl;}
private: int _year; int _month;int _day;
};
int main()
{Date d1(2020, 2, 3);Date d2(2021, 2, 3);return 0;
}
总结:
0、析构函数只能有一个,如果没有显示定义,编译器会自动生成
1、析构函数只能被调用一次,且不能显示调用,只能在对象生命周期结束时会自动调用。
2、当类没有资源释放和清理,可以不写析构函数。
3、编译器默认生成的析构函数并非没有作用,当成员变量存在自定义类型时,会自动调用自定义类型的析构函数。
构造顺序:全局变量->静态变量->普通变量
析构顺序:普通变量->静态变量->全局变量
推荐阅读
拷贝构造 与 运算符重载
C++ 构造函数 与 析构函数相关推荐
- C++ 笔记(17)— 类和对象(构造函数、析构函数、拷贝构造函数)
1. 构造函数 构造函数是一种特殊的函数(方法),在根据类创建对象时被调用.构造函数是一种随着对象创建而自动被调用的函数,它的主要用途是为对象作初始化. 构造函数的名称与类的名称是完全相同的,并且不会 ...
- php构造和析构方法,php5构造函数与析构函数实例
自php5起,有了构造函数与析构函数. 这使得php更富有面向对象的魅力了. 在php4时,构造函数用的是与类同名的函数来进行构造这个动作. 例如: 复制代码 代码示例: /* * myclass.p ...
- 提高C++性能的编程技术笔记:构造函数和析构函数+测试代码
对象的创建和销毁往往会造成性能的损失.在继承层次中,对象的创建将引起其先辈的创建.对象的销毁也是如此.其次,对象相关的开销与对象本身的派生链的长度和复杂性相关.所创建的对象(以及其后销毁的对象)的数量 ...
- c++, 派生类的构造函数和析构函数 , [ 以及operator=不能被继承 or Not的探讨]
说明:文章中关于operator=实现的示例,从语法上是对的,但逻辑和习惯上都是错误的. 参见另一篇专门探究operator=的文章:<c++,operator=>http://www.c ...
- C++中的构造函数VS析构函数
1.构造函数 类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行.构造函数的名称与类的名称的完全相同的,并且不会返回任何数据类型,也不会返回void.构造函数用于为某些成员变量设置初 ...
- 多继承的构造函数和析构函数
//程序2:多继承的构造函数 与 析构函数 #include<iostream> using namespace std;class A { public: A() { cout<& ...
- c++ 构造函数析构函数 数据安全_C++知识点 16:构造函数和析构函数的语法
#define _CRT_SECURE_NO_WARNINGS #include using namespace std;// 创建一个类( 类内包括: 2个构造函数,一个析构函数) class Pe ...
- 多重继承的构造函数和析构函数
多重继承的构造函数和析构函数的执行顺序: //此处不做注释和说明了,看程序能读懂的 #include <iostream> using namespace std; class base1 ...
- C++中构造函数和析构函数
[注]致力于将知识讲明白!不懂请留言! 构造函数 定义 它是一种特殊的方法.主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中. 另外,一个类可以有 ...
- c++ map 析构函数_C++学习刷题6--C++类的使用:构造函数、析构函数和类的使用
一.前言 本部分为C++语言刷题系列中的第4节,主要讲解这几个知识点:构造函数.析构函数和类的使用.欢迎大家提出意见.指出错误或提供更好的题目! 二.知识点讲解 由以前知识可知,类的实现中包含成员变量 ...
最新文章
- 问答系统的搭建与财报知识图谱关系比较密切 问题相似度方面
- SVN Unable to connect to a repository at URL问题解决
- 数据中心停机事故的教训:关注基础设施
- Matlab:序列分析法MATLAB代码
- 电脑删除linux系统,我的电脑现在装有XP和Linux两个系统,现在想删除Linux系统,开机不用选直接进入XP。不知怎么做??...
- Qt修炼手册12_线程同步与线程等待条件
- 基于ASP.NET的comet简单实现
- Akka并发编程——第三节:Actor模型(二)
- 04737 c++ 自学考试2019版 第六章课后练习 程序设计题 1
- WebApi系列(从.Net FrameWork 到 .Net Core)
- 【JavaSE】黑马程序员 刘意 基础部分笔记
- 网络协议梳理(四)(socket、想要实现高并发,可以通过以下四种方式)
- 安卓系统修改分辨率.2022.01.05
- 啦啦外卖独立版41.4+全插件+可运营版本+开源(亲测100%可用)
- Spark2.1.1中用各种模式运行计算圆周率的官方Demo
- C++ Vector初始化(一维,多维)
- cachecloud安装指南
- 苹果App Store搜索出Bug,网友:完美避开所有正确答案
- 多径效应及其消除方法
- UltraScale Architecture Clocking Resources
热门文章
- 2013二级计算机c语言50,2013年计算机二级C语言课后模拟题五及答案
- 乌班图服务器系统怎么配ip,Ubuntu server14-04 服务器双网卡怎么配置静态ip
- mysql like n_MySQL LIKE 子句
- 基于JAVA+SpringBoot+Mybatis+MYSQL的宝妈购母婴用品商城
- 基于JAVA+SpringMVC+Mybatis+MYSQL的网上商城系统
- KUDU数据导入尝试一:TextFile数据导入Hive,Hive数据导入KUDU
- CodeForces #549 Div.2 ELynyrd Skynyrd 倍增算法
- 子集生成-增量构造法||位向量法
- 顺序线性表 ---- ArrayList 源码解析及实现原理分析
- 递归,复制对象,找质数,判断数组