构造函数
类的初始化分为两种:有且只有一次的初始化以及根据类的条件初始化
构造函数可以对类进行初始化,并具有如下的特点
的规则及特点 :
构造函数的功能是对类成员进行初始化
对象实例化时自动被调用 | 与类同名 |
---|---|
没有返回值 | 可以有多个 |
有多个重载形式 | 实例化对象时仅用到一个构造函数 |
用户未定义时,编译器自动生成 |
可以用无参、有参及重载构造函数。构造参数无参或者每个参数都有默认值称为默认构造函数。
如定义类为 Teacher 可分别定义重载构造函数Teacher();
与Teacher(string name,int age=20);
注意这里两个重载构造函数与类的名相同,有参构造函数也可以指定默认值。此外,如果name也给定了默认值的话,实例化无参对象的时候 如Teather t1;
系统无法区分调用的是无参的还是有参的。
初始化列表
定义完构造函数后用冒:
,赋值用()
举例比较初始列表与构造函数,如下图可以看出由于m_dPi已经定义为常量,像左图这样赋值会报错,此时可以用初始化列表的方法。
拷贝构造函数
格式 类名(const 类名&变量名)
在通过同类型的对象实例化另外的对象或者作为参数传入时都会调用拷贝构造函数。拷贝构造参数不可重载。
看如下代码片段,已经在之前拷贝构造函数内部写下输出“拷贝构造函数”
的语句
void test(Student t){}; //调用实例化对象
int main(void)
{
Student stu; //实例化对象stu
Student stu1=stu; //通过stu实例化stu1
test(stu); //stu作为参数传入test
可以看出实例化时调用了一次无参构造函数,而通过stu实例化stu1以及传参都会调用拷贝参数。
析构函数
在对象销毁时自动调用,归还系统资源。
格式 ~类名()
没有任何参数,不可能重载,没有定义时系统自动生成
对象的整个生命过程如下
最后做一个代码练习,要求如下
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
//无参构造函数
Student()
{
m_strName="";
cout<<"无参构造函数"<<endl;
}
//有参构造函数
Student(string _name)
{
m_strName=_name;
cout<<"有参构造函数"<<endl;
}
//拷贝构造函数
Student(const Student&stu)
{
cout<<"拷贝构造函数"<<endl;
}
//析构函数
~Student()
{
cout<<"析构函数"<<endl;
}
void setName(string);
string getName();
private:
string m_strName;
};
//类外定义函数
void Student::setName(string _name)
{
m_strName=_name;
}
string Student::getName()
{
return m_strName;
}
void test(Student t){};
int main(void)
{
Student stu;
Student stu1=stu;
test(stu);
stu.setName("csdn");
// 打印对象的数据成员
cout<<stu.getName()<<endl;
return 0;
}
运行结果如下
可见栈型会自动调用析构函数。