【C++】3___对象的初始化和清理

发布于:2024-12-06 ⋅ 阅读:(32) ⋅ 点赞:(0)

目录

构造函数和析构函数

1.1主要作用

 1.2语法

 1.3构造函数的分类及调用

 1.4浅拷贝与深拷贝


构造函数和析构函数

1.1主要作用
  • 构造函数:创建对象时为对象的成员属性赋值,由编译器自动调用,无需手动调用。
  • 析构函数:对象销毁前系统自动调用,执行一些清理工作。
 1.2语法
  • 构造函数:类名(){  }
  1. 构造函数,没有返回值也不写void
  2. 函数名称与类名相同
  3. 构造函数可以有参数,因此可以发生重载
  4. 程序在调用对象时会自动调用构造,无需手动调用,而且只会调用一次
  • 析构函数
  1. 析构函数,没有返回值也不写void
  2. 函数名称与类名相同,在前面加上 ~
  3. 析构函数不可以有参数,因此不可以发生重载
  4. 程序在对象销毁前会自动调用析构,无需手动调用,而且只会调用一次
#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构造函数的分类及调用
  • 分类:
  1. 普通构造函数(无参构造函数、有参构造函数)
  2. 拷贝构造函数
  • 调用:
  1. 括号法
  2. 显示法
  3. 隐式转换法
  • 构造函数调用规则
  1. 如果用户定义有参构造函数,c++不在提供默认无参构造,但会继续提供默认拷贝构造
  2. 如果用户定义拷贝构造函数,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;
}
  •   注意
  1. 在无参构造函数的括号法调用中,不能写成 person  P1( );  原因是编译器可能会认为这是一个函数声明,不会认为是在创建对象。
  2. 在显示法中,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;
}