C++ DAY8 对象的初始化和清理。构造函数的分类及调用,构造函数调用时机

1.构造函数和析构函数

对象的初始化和清理非常重要

构造函数和析构函数是编译器自动调用的,如果我们自己不设置,编译器强制实现。

注意:编译器这两个函数是空实现。即自己写了就用我们写的函数。

构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。

析构函数:主要作用在于对象销毁前系统自动调用,系统进行一些清理活动。

构造函数 语法:类名(){}

1.没有返回值,也不写void

2.函数名称与类名相同

3.构造函数有参数,因此可以发生重载

4.程序在调用构造时会自动调用,无须手动调用,且只会调用一次

析构函数 语法:~类名(){}

1.没有返回值,也不写void

2.函数名称与类名相同,前面加上符号~

3.析构函数不可以有参数,所以不可以重载

4.程序在对象销毁会自动调用,无须手动调用,且只会调用一次

class person
{
public:
	person()
	{
		cout << "构造函数调用" << endl;
	}
	~person()
	{
		cout << "析构函数调用" << endl;
	}
};

void test1()
{
	person p;    //这里只是创建了一个对象,还没调用
}

int main()    //类外
{
	test1();   //说明构造,析构函数是自动调用的
	person p;  //在test1中函数调用完就释放。而主函数中的p在按下任意键后才会被销毁
	system("pause");              
	return 0;   
}

2.构造函数的分类及调用

两种分类方式:

按参数分:有参构造和无参构造

按类型分:普通构造和拷贝构造

三种调用方式:

括号法

显示法

隐式转换法

注意:

(1)调用默认构造函数时不要加()

(2)不要利用拷贝函数初始化匿名对象

如person(p3);会报错  因为编译器把person(p3) 等价于 person p3 重复构造对象。

class person
{
public:
	person()
	{
		cout << "无参构造函数调用" << endl;
	}

	person(int a)
	{
		age = a;//相当于对年龄初始化
		cout << "有参构造函数调用" << endl;
	}
	//拷贝构造函数
	person(const person &p) //用当前类名创造一个参数,用引用的形式,再加上const限制修改类中属性
								//目的是复制个一模一样的数据
	{
		age = p.age;//谁调用这个拷贝函数,就把传入的数据拷贝到当前类的属性上
		cout << "拷贝构造函数调用" << endl;
	}
	int age;
};

void test1()
{
	括号法
	//person p1;  //默认构造函数的调用
	person p1();编译器会认为这是个函数声明,没有实例化一个对象
	//person p2(10); //有参构造函数的调用
	拷贝构造函数的调用
	//person p3(p2);    //拷贝函数的格式,代表将p2的数据复制到p3里
	//cout << p3.age << endl; //  此时p2的年龄已被拷贝到p3里
	//显示法
	person p1;
	person p2 = person(10);  //表明要传输一个10给构造函数中的a
	//显示法拷贝构造函数
	person p3 = person(p2);  //显示法语法
	person(20);  //为匿名对象,这也是个对象。当前行执行结束系统就回收
	//隐式转换法
	person p4 = 30;  //相当于person p4 = person(30) 有参构造
	person p5 = p4;//拷贝构造

}

int main()   
{
	test1();   
	system("pause");              
	return 0;   
}

3.构造函数调用时机

三种情况

(1)使用一个已经创建完毕的对象来初始化一个新对象

(2)值传递的方式给函数参数传值

(3)以值方式返回局部对象(有不懂的看视频p108)

class person
{
public:
	person()
	{
		cout << "无参构造函数调用" << endl;
	}

	person(int a)
	{
		m_age = a;
		cout << "有参构造函数调用" << endl;
	}
	//拷贝构造函数
	person(const person &p)
	{
		m_age = p.m_age;
		cout << "拷贝构造函数调用" << endl;
	}
	int m_age;
};

void test1()
{
	person p1(20);
	person p2(p1);
}

//2.以值传递的方式调用拷贝函数
void zhi(person p)
{
	int a = p.m_age;
	cout << a << endl;
}

void test2()
{
	person p(20);
	zhi(p);  //值传递就是复制一份再传输。这里是把对象p的所有属性传输到zhi函数中				//所以相当于用了拷贝函数
}

//3.值方式返回局部对象
person work()  //实参不能返回,所以要按照这个对象拷贝一个新的对象给test03(),再返回
{
	person p1;   //这个p1执行完以后就释放了
	return p1;
}

void test03()
{
	person p = work();   //此处编译器已优化,观察不到拷贝现象
						//此处的p不等同于p1,两个是不同对象。p1先复制一个,再释放。然后复制的给了p
					//所以p和p1的地址也不相同
}

int main()   
{
	//test2();   
	test03();
	system("pause");              
	return 0;   
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值