构造函数
概念
构造函数
是一个
特殊的成员函数,名字与类名相同
,没有返回值,
创建类类型对象时由编译器自动调用
,以保证
每个数据成员都有 一个合适的初始值,并且
在对象整个生命周期内只调用一次
。
class Date
{
public:
Date()
{
_year = 1;
_month = 1;
_day = 1;
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
Date类中的Date()函数就是构造函数,函数名与类名相同,没有返回值,在类创建对象时自行调用
特性
其特征如下:
1.
函数名与类名相同。
2.
无返回值。
3.
对象实例化时编译器
自动调用
对应的构造函数。
4.
构造函数可以重载。
class Date
{
public:
Date()//无参构造函数
{
_year = 1;
_month = 1;
_day = 1;
}
Date(int year, int month, int day)//有参构造函数
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
在通过不同的方式创建对象时编译器会自适应的调用不同的构造函数
int main()
{
Date d1; //调用无参构造函数
d1.Print();
Date d2(2023, 7, 21);//调用带参构造函数
d2.Print();
return 0;
}
上述代码也同时体现了构造函数可以重载的特性
也可以利用缺省函数将上述两个不同的构造函数合并为一个
class Date
{
public:
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Print();
Date d2(2023);
d2.Print();
Date d3(2023, 7);
d3.Print();
Date d4(2023,7,20);
d4.Print();
return 0;
}
也可以将缺省值放在类成员变量声明的位置
Date()
{
_month = 7;
_day = 20;
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
int _year=1;
int _month=1;
int _day=1;
};
如果类中没有显式定义构造函数,则
C++
编译器会自动生成一个无参的默认构造函数,一旦
用户显式定义编译器将不再生成。
C++
把类型分成内置类型
(
基本类型
)
和自定义类型。内置类型就是语言提供的数据类
型,如:
int/char...
,自定义类型就是我们使用
class/struct/union
等自己定义的类型,看看
下面的程序,就会发现编译器生成默认的构造函数会对自定类型成员
_t
调用的它的默认成员
函数
无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为
是默认构造函数。
析构函数
概念
析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由
编译器完成的。而
对象在销毁时会自动调用析构函数,完成对象中资源的清理工作
。
析构函数名是在类名前加上字符
~
。
例如我们需要写一个栈,在栈使用完后我们需要释放内存空间,在C语言阶段我们通常会写一个销毁函数STDestroy(),但是许多人会忘记调用,我们可以利用析构函数自行调用的特点,将释放内存空间的语句写在析构函数中,并且将初始化函数写在构造函数中。
class Stack
{
public:
Stack(int n=4)//构造函数
{
_a = (int*)malloc(sizeof(int) * n);
_top = _capacity = 0;
}
~Stack()//析构函数
{
free(_a);
_a = nullptr;
_top = _capacity = 0;
}
private:
int* _a;
int _top;
int _capacity;
};
特性
析构函数
是特殊的成员函数,其
特征
如下:
1.
析构函数名是在类名前加上字符
~
。
2.
无参数无返回值类型。
3.
一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构
函数不能重载
4.
对象生命周期结束时,
C++
编译系统系统自动调用析构函数。
例题:
在函数F中,本地变量a和b的构造函数(constructor)和析构函数(destructor)的调用顺序是: ( )
Class A;
Class B;
void F()
{
A a;
B b;
}
因为类创建的对象是存储在栈帧空间里的,遵循后进先出的规则,先调用a的构造函数,在调用b的构造函数,在销毁栈帧时,b先销毁,所以先调用b的析构函数,最后调用a的析构函数
class A
{
public:
A()
{
cout << "A()" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
class B
{
public:
B()
{
cout << "B()" << endl;
}
~B()
{
cout << "~B()" << endl;
}
};
void F()
{
A a;
B b;
}
int main()
{
F();
return 0;
}