对象的初始化和清理
C++中使用构造函数和析构函数来实现对象的初始化和清理
编译器默认会实现这两个函数,但为空实现。
构造函数语法:
//语法:类名(){}
//没有返回值,也没有void
//函数名称和类名相同
//构造函数可以有参数,因此可以发生重载
//程序在调用对象时会自动调用构造函数,且只调用一次
析构函数语法:
//~类名(){}
//没有返回值,也没有void
//函数名称和类名相同
//程序在调用对象时会自动调用构造函数,且只调用一次
//不可以有参数,不可以重载
举例
//class Person
{
public://注意是在public作用域下
Person()
{
cout<<"构造函数的调用"<<endl;
}
~Person(){
cout<<"析构函数的调用"<<endl;
}
}
void test(){
Person p2;//打印出"构造函数的调用"和"析构函数的调用"
//局部变量的数据在栈上,test执行完以后会释放这个对象
}
int main(){
Person p1;//打印出"构造函数的调用"
test();
}
构造函数的分类和调用
按照参数:有参构造和无参构造(默认)
按照类型:普通构造函数和拷贝构造函数
//有参构造函数
Person(int a){
int age=a;
}
//拷贝构造函数
Person(const Person &p){
//拷贝出一个一摸一样的对象出来,但是不能修改源对象,所以要加const
age=p.age;//将传入的对象所有属性赋值给新的对象
}
调用
void test(){
//括号法
Person p;//调用默认构造函数,注意在调用默认构造函数时,不要加()
Person p();//会被编译器认为是函数的声明
Person p1(18);//调用有参构造函数
Person p2(p1);//调用拷贝构造函数
//显示法
Person p3=Person(10);
Person p4=Person(p3);//=右边为匿名对象,匿名对象的当前行结束后,系统自动回收该对象
//不要用拷贝构造函数来初始化匿名对象
Person(p4);//编译器:Person(p4)===》Person p4,被认为是对象的声明,报错重定义
//隐式转换法
Person p5=10;
Person p6=p5;
}
拷贝构造函数调用时机
-
使用一个已经创建完毕的对象来初始化一个新对象
//如上
-
值传递的方式给函数参数传值
void work(Person p){ } void test(){ Person p; work(p); }
-
值传递方式返回局部对象
Person work(){ Person p2; return p2; } void w=test(){ Person p1=work(); }
拷贝函数调用规则
默认情况下,C++编译器至少给一个类添加:构造、析构、拷贝构造函数
- 如果自定义了有参构造函数,C++不再提供默认无参构造函数,但会提供默认拷贝构造函数
- 如果自定义了拷贝构造函数,C++不再提供其他构造函数