构造函数:在创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用
析构函数:在对象销毁前系统自动调用,执行一些清理工作
(如果自己不写这两个函数,编译器会自动提供这两个函数,由编译器自动调用,由编译器提供的这两个函数是空实现)
构造函数:
1、没有返回值也不写void
2、名称与类名相同
3、可以有参数,可以发生重载
4、自动调用且调用1次
按照参数分类:有参构造和无参构造
按照类型分类:普通构造和拷贝构造
拷贝构造函数:把一个对象的所有成员属性拷贝到另一个类中
Person(const Person & p){ //其原理等同于为指向const 的const指针(但不是指针啊)
age = p.age;
name = p.name;
}
main: Person p3(p2) ; //把p2的属性传入p3
另外:调用无参的构造函数不能加括号:Person p2();而是直接写Person p2;会误以为是一个函数声明
析构函数:
1、没有返回值也不写void
2、名称与类名相同,前面加上~
3、不可以有参数,不可以发生重载
4、自动调用且调用1次
注意:只有在对象执行完销毁时才执行析构函数,比如在main()中实例了一个对象,则会在整个程序运行最后才会调用析构函数
对于拷贝构造函数使用:
1、使用一个已经创建完毕的对象来初始化一个新对象
2、值传递的方式给函数参数传值
void dowork(Person p1){
//此处更改p1内的值并不会影响原类的属性,因为是值传递的方式
}
void test2 (){
Person p;
doWork(p);
}
3、值方式返回局部对象(同样调用的是拷贝构造函数)
Person dowork2(){
Person p1;
return p1; //此处是值传递的方式,同样不会影响p1的成员
}
void test3(){
Person p = dowork2(); //值传递的方式把p1传给p,两者成员互不影响
}
构造函数调用规则:
默认情况下:编译器至少给一个类添加3个函数
1、默认构造函数:无参、函数体为空
2、默认析构函数;无参、函数体为空
3、默认拷贝构造函数,对属性进行值拷贝(值传递的思想)
对于构造函数:当用户写了有参构造函数,则无参构造函数不再提供,当用户写了3,则其他的构造函数不在提供
即如果用户只写了有参构造函数,在main()中又写了Person p1;则会报错,因为编译器不再自动提供默认无参构造函数
如果用户只写了拷贝构造函数,在main()中又写了Person p1;或者Person p2 (10);则会报错,因为编译器不再自动提供默认无参构造函数和有参构造函数