对象的初始化和清理
- 构造函数和析构函数
构造函数:主要作用在创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无需手动。
析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作。
两个函数时必须的,如果不提供构造和析构,编译器会提供编译器提供的构造函数和析构函数是空实现。
class Person
{
public:
// 构造函数
//没有返回值 不写void
//函数名 与类同名
//构造函数可以有参数,可以重载
//创建对象的时候,构造函数会自动调用仅一次。
Person()
{
cout << "Person构造函数的调用" << endl;
}
//析构函数 进行清理操作
//没有返回值 没有void
//函数名和类名相同,名前加~
//析构函数不可以有参数,不可以发生重载
//对象在销毁前会自动调用,且只一次
~Person()
{
cout << "Person析构函数的调用" << endl;
}
};
//
void test01()
{
Person p;//在栈上的数据,test01执行完后,释放这个对象
}
int main()
{
test01();
system("pause");
return 0;
}
若将函数 test01的内容直接卸载主函数中,并删除函数
int main()
{
Person p;
system("pause");
return 0;
}
结果将会只有
p 会在之后释放。
- 构造函数的分类和调用
两种分类方法:
按参数分: 有参构造 无参构造
按类型分:普通构造 拷贝构造
参数分:
1 有参构造
Person(int a) //分类为 有参构造
{
age = a;
cout << "Person的有参构造函数调用" << endl;
}
2 无参构造
Person() //分类为 无参构造(默认构造)
{
cout << "Person的无参构造函数调用" << endl;
}
按类型分:
1 普通构造 以上例子均为普通构造
2 拷贝构造
Person(const Person& p)//以引用来传入同样的类型 且不可修改
{//将传入的p身上的属性拷贝到当前Person类的对象身上
age = p.age;
}
三种调用方法:
括号法、显示法、隐式转换法。
1 括号法(常用)
Person(const Person& p)//以引用来传入同样的类型 且不可修改
{//将传入的p身上的属性拷贝到当前Person类的对象身上
age = p.age;
}
void test01()
{
//括号法
Person p;//默认构造函数的调用
Person p1(10);//有参构造函数的调用
Person p2(p1);//拷贝函数的调用
//注意1 调用默认构造函数时 不要加括号。
//如 Person p(); 会被认作是函数声明
}
2 显示法
//显示法
Person p;
Person p1 = Person(10);//调用有参构造
Person p2 = Person(p1);
// Person(10);//匿名对象。在上面 等号左侧为其名称
// 特点:当前 行执行完毕后,系统会立即回收匿名对象
//注意2 不要用拷贝构造函数 初始化匿名对象
//即 Person(p2);
//编译器会认为 Person(p2) 是 Person p2 对象声明
3 隐式转换法
//隐式转换法
Person p4 = 10;//即 Person p4 = Person(10);有参构造
Person p5 = p4;//拷贝构造