目录
类的构造函数
- 功能:在创建类的新对象时,由系统自动调用,用给定的值对数据成员初始化
- 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回void
- 构造函数可以重载
- 一般将构造函数定义为公有成员函数
- 不可以通过对象名调用构造函数,即的d1.Date()是非法的
- 可以直接通过构造函数名调用构造函数来创建对象,如
Date d1;
d1 = Date(2018); // 等式的右边创建了一个对象,并将它赋给d1
class Date
{
int year, month, day;
public:
Date() // 重载构造函数1
{
year = 2018; month = 8; day = 25;
}
Date(int y) // 重载构造函数2
{
year = y; month = 8; day = 25;
}
Date(int y, int m) // 重载构造函数3
{
year = y; month = m; day = 25;
}
Date(int y, int m, int d): year(y), month(m), day(d) {} // 采用初始化列表来初始化字段,重载构造函数4
void showDate()
{
cout << year << '.' << month << '.' << day << endl;
}
};
int main()
{
Date d1; //自动调用构造函数1
Date d2(2018); //自动调用构造函数2
Date d3(2018, 8); //自动调用构造函数3
Date d4(2018, 8, 25); //自动调用构造函数4
}
上面代码定义了四个重载的构造函数
类的析构函数
- 功能:系统在撤销对象时,自动调用它来做一些清理工作
- 析构函数的名称是类的名称前加~,用来与构造函数区分
- 析构函数没有参数,且不会返回任何类型,也不会返回void
- 析构函数不可以重载,一个类只能定义一个析构函数
- 一般将析构函数定义为公有成员函数
- 析构函数可以显示的调用,也可以由系统自动调用
- 类成员变量无指针成员时,不需要显示定义析构函数
#include <iostream>
#include <string.h>
using namespace std;
class Student
{
char num[10];
char *name;
int score;
public:
Student(char *nump, char *namep, int s)
{
if(nump)
strcpy(num, nump);
else
strcpy(num, " ");
if(namep)
{
name = new char[strlen(namep)+1];
strcpy(name, namep);
}
else
name = NULL;
score = s;
}
~Student()
{
if(name)
delete []name;
}
};
析构函数被自动调用的时机:
1)当对象是系统自动创建的,则在对象的作用域结束时,系统自动调用析构函数。如在函数体内定义了一个局部对象,当函数执行结束时,系统要撤销该对象,在撤销该对象前,系统先自动调用析构函数,然后再撤销该对象本身的存储空间。若定义一个全局对象,则在程序结束时(即main函数结束时),该对象的析构函数被自动调用。
2)若一个对象是通过new运算符动态创建的,则在使用delete运算符释放它的时候,自动调用析构函数。
调用构造函数和析构函数的时机(对象的生存周期)
变量分为全局变量和局部变量,又分为动态变量和静态变量。对象实际上就是变量,所以对象也有全局对象和局部对象,动态对象和静态对象。
构造函数在创建对象时系统自动调用,析构函数在撤销对象时系统自动调用,但不同存储类别的对象自动调用构造函数和析构函数的时机不同:
1)全局对象(总是静态的)--程序开始执行时,系统自动创建对象并调用构造函数;程序结束时,系统在撤销对象前调用析构函数。(程序开始执行时,是指main()函数开始执行时;程序结束时,是指main()函数执行结束时)
2)局部动态对象--当程序执行进入作用域,在定义对象处系统自动创建对象,调用构造函数;退出作用域时,系统在撤销对象前调用析构函数。
3)局部静态对象--当程序首次到达定义对象处,系统自动创建对象,并调用构造函数;程序结束时,系统在撤销对象前调用析构函数。
4)动态申请对象--使用new产生对象时,系统自动调用构造函数,使用delete撤销对象时,系统自动调用析构函数。
缺省构造函数与缺省析构函数
1)缺省构造函数
- 在C++的一个类中,如果构造函数没有参数,或者构造函数的所有参数都有默认值,就可以称其为缺省构造函数。
- 如果类中没有定义构造函数,则编译系统自动生成一个不带参数的缺省构造函数:
className :: className()
{ }
- 若在类中已经存在构造函数,则编译系统不再自动生成缺省构造函数。
- 一个类中,只能有一个缺省构造函数。
第一种形式:
class Date
{
int year, month, day;
public:
Date() // 缺省构造函数
{
year = 2018; month = 8; day = 25;
}
};
int main()
{
Date d1; //自动调用构造函数
}
第二种形式:
class Date
{
int year, month, day;
public:
Date(int y=2018, int m=8, int d=25) // 缺省构造函数
{
year = y; month = m; day = d;
}
};
int main()
{
Date d1; //自动调用构造函数
}
2)缺省析构函数
- 如果类中没有定义析构函数,则编译系统自动生成一个缺省析构函数:
className :: ~className()
{ }
- 当类中有动态申请的存储空间时,必须显示定义析构函数,来撤销动态存储空间。