目录
构造函数和析构函数
1.1主要作用
- 构造函数:创建对象时为对象的成员属性赋值,由编译器自动调用,无需手动调用。
- 析构函数:对象销毁前系统自动调用,执行一些清理工作。
1.2语法
- 构造函数:类名(){ }
- 构造函数,没有返回值也不写void
- 函数名称与类名相同
- 构造函数可以有参数,因此可以发生重载
- 程序在调用对象时会自动调用构造,无需手动调用,而且只会调用一次
- 析构函数
- 析构函数,没有返回值也不写void
- 函数名称与类名相同,在前面加上 ~
- 析构函数不可以有参数,因此不可以发生重载
- 程序在对象销毁前会自动调用析构,无需手动调用,而且只会调用一次
#include<iostream>
using namespace std;
class person {
public:
// 构造函数
person() {
cout<<"构造函数的调用"<<endl;
}
// 析构函数
~person() {
cout<<"析构函数的调用"<<endl;
}
};
void test(){
person P;
}
int main(){
test();
return 0;
}
1.3构造函数的分类及调用
- 分类:
- 普通构造函数(无参构造函数、有参构造函数)
- 拷贝构造函数
- 调用:
- 括号法
- 显示法
- 隐式转换法
- 构造函数调用规则
- 如果用户定义有参构造函数,c++不在提供默认无参构造,但会继续提供默认拷贝构造
- 如果用户定义拷贝构造函数,c++不会再提供其他构造函数
代码说明
#include<iostream>
using namespace std;
class person {
public:
person() {
cout<<"无参构造函数的调用"<<endl;
}
person(int a) {
age = a ;
cout<<"有参构造函数的调用"<<endl;
}
// 拷贝构造函数
person(const person &P) {
age = P.age;
cout<<"拷贝构造函数的调用"<<endl;
}
~person() {
cout<<"析构函数的调用"<<endl;
}
int age;
};
void test(){
// 1.括号法
person P1;
person P2(10);
person P3(P2);
cout<<"P2="<<P2.age<<endl;
cout<<"P3="<<P3.age<<endl;
// 2.显示法
// person P1;
// person P2 = person(10);
// person P3 = person(P2);
// 3.隐式转换法
// person P4 = 10; //有参构造函数
// person P5 = P4; //拷贝构造函数
}
int main(){
test();
return 0;
}
- 注意
- 在无参构造函数的括号法调用中,不能写成 person P1( ); 原因是编译器可能会认为这是一个函数声明,不会认为是在创建对象。
- 在显示法中,person P2 = person (10); "person (10)" 称为匿名对象。特点:当前行执行结束后会立即回收掉匿名对象。
1.4浅拷贝与深拷贝
在使用编译器默认的拷贝构造函数(浅拷贝)时,通常在指针拷贝后,释放指针时会出现二次释放指针的问题。使用深拷贝来解决。
#include<iostream>
using namespace std;
class person {
public:
person() {
cout<<"无参构造函数的调用"<<endl;
}
person(int a,int height) {
m_Age = a;
m_Height = new int(height);
cout<<"有参构造函数的调用"<<endl;
}
// 拷贝构造函数
person(const person &P) {
cout<<"拷贝构造函数的调用"<<endl;
// 自己写拷贝构造函数解决浅拷贝问题
m_Age = P.m_Age;
// m_Height = P.m_Height; //浅拷贝
m_Height =new int(*P.m_Height);
}
~person() {
//析构代码,将堆区开辟数据做释放操作
if(m_Height != NULL){
delete m_Height;
m_Height = NULL;
}
cout<<"析构函数的调用"<<endl;
}
int m_Age;
int *m_Height;
};
void test(){
person P1(18,180);
cout<<"P1.m_Age="<<P1.m_Age<<" P1.m_Height="<<*P1.m_Height<<endl;
person P2(P1);
cout<<"P2.m_Age="<<P2.m_Age<<" P2.m_Height="<<*P2.m_Height<<endl;
}
int main(){
test();
return 0;
}