C++(16)对象的构造和析构

构造函数

定义
1)C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数;
2)构造函数在定义时可以有参数;
3)没有任何返回类型的声明。


调用
自动调用:一般情况下C++编译器会自动调用构造函数
手动调用:在一些情况下则需要手工调用构造函数

析构函数

定义
1)C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫做析构函数
语法:~ClassName()
2)析构函数没有参数也没有任何返回类型的声明
3)析构函数在对象销毁时自动被调用


调用
C++编译器自动调用

示例程序
#include <iostream>
#include <string.h>
using namespace std;

class Student
{
public:
	// 构造函数:函数名和类名相同   函数没有返回值
	// 构造函数一般情况下,不需要手动调用,系统自动调用:初始化对象的时候调用
	Student()
	{
		m_age = 10;
		strcpy(m_name, "abc");
		printf ("构造函数被调用\n");
	}

	// 析构函数:函数和类名相同,函数前加一个 ~ ,析构函数没有返回值
	// 回收对象资源,当对象被释放的时候 系统自动调用析构函数回收对象资源
	~Student()
	{
		printf ("析构函数被调用\n");
	}

private:
	int m_age;
	char m_name[20];
};

int main()
{
	{
		// 对象 不能像结构体一样直接初始化
		// 类 使用构造函数来 初始化 对象
		Student s;
		cout << "------------" << endl;

	}

	cout << "hello world" << endl;
    return 0;
}


执行结果:
构造函数被调用
------------
析构函数被调用
hello wrold

构造函数的分类


class  Test1
{
public:
	Test1() 
	{
		m_a = 0;
		m_b = 0;
		cout<<"无参构造函数被调用"<<endl;
	}

	Test1(int a)
	{
		m_a = a;
		m_b = 0;
		cout<<"一个参数的构造函数被调用"<<endl;
	}

	Test1(int a,int b)
	{
		m_a = a;
		m_b = b;
		cout<<"两个参数的构造函数被调用"<<endl;
	}

	Test1(const Test1 &obj)
	{
		m_a = obj.m_a;
		m_b = obj.m_b;
		cout<<"拷贝构造函数被调用"<<endl;
	}
	
	~Test1()
	{
		cout<<"析构函数被调用"<<endl;
	}
	void printT1()
	{
		cout<<"a = "<<m_a<<",b = "<<m_b<<endl;
	}
private:
	int m_a;
	int m_b;
};

int main()
{
	Test1 t;
	t.printT1();

	//括号
	Test1 t1(10);
	Test1 t2(10,20);
	t1.printT1();
	t2.printT1();

	//等号
	Test1 t3 = 10;
	Test1 t4 = (10,20);
	t3.printT1();
	t4.printT1();

	//手动调用
	Test1 t5 = Test1();
	Test1 t6 = Test1(20,30);
	t5.printT1();
	t6.printT1();

	//用一个对象 对 另一个对象进行 初始化 会调用 拷贝构造函数
	Test1 t7(t1);
	t7.printT1();

	Test1 t8 = t2;
	t8.printT1();

	Test1 t9 = Test1(t3);
	t9.printT1();

	return 0;
}

执行结果:
无参构造函数被调用
a = 0,b = 0
一个参数的构造函数被调用
两个参数的构造函数被调用
a = 10,b = 0
a = 10,b = 20
一个参数的构造函数被调用
一个参数的构造函数被调用
a = 10,b = 0
a = 20,b = 0
无参构造函数被调用
两个参数的构造函数被调用
a = 0,b = 0
a = 20,b = 30
拷贝构造函数被调用
a = 10,b = 0
拷贝构造函数被调用
a = 10,b = 20
拷贝构造函数被调用
a = 10,b = 0
析构函数被调用
析构函数被调用
析构函数被调用
析构函数被调用
析构函数被调用
析构函数被调用
析构函数被调用
析构函数被调用
析构函数被调用
析构函数被调用

二个特殊的构造函数
1)默认无参构造函数
当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空
2)默认拷贝构造函数
当类中没有定义拷贝构造函数时,编译器默认提供一个默认拷贝构造函数,简单的进行成员变量的值复制


拷贝构造函数的调用时机:
1、Test t2 = t1; // 用对象 t1 去初始化t2
2、Test t2(t0); // 用对象 t0 去初始化t2
3、PrintObj(t0); // 做函数参数的时候
4、t1 = test(); // 函数返回值返回对象


一些注意点

// 传对象的时候 要传对象的引用(指针)  否则调用对象的拷贝构造函数
// void func(Test1_1 obj)
void func(Test1_1 &obj)  // Test1_1 *const obj = &t1
{
	obj.print();
}

// 对象做函数参数
int main1_4()
{
	Test1_1 t1(1,2);

	// 当一个函数的参数是一个对象的时候
	func(t1);


	return 0;
}



void func(Test1_1 obj)执行结果:
两个参数的构造函数被调用
拷贝构造函数被调用
a = 1,b = 2
析构函数被调用
析构函数被调用


void func(Test1_1 &obj) 执行结果:
两个参数的构造函数被调用
a = 1,b = 2
析构函数被调用
Test1_1 func()
{
	Test1_1 t1;

	return t1;
}

// 对象做函数返回值
int main1_5()
{
	// 不接收返回值, 会产生一个匿名对象,用 t1 去初始化, 调用拷贝构造函数
	// 匿名对象没人收 立马被释放
	// func();

	// 不接收返回值, 会产生一个匿名对象,用 t1 去初始化, 调用拷贝构造函数
	// 用 t 对匿名对象命名
	// Test1_1 t = func();

	// Test1_1 t2;	
	// 用一个已经存在的对象去收 函数返回的对象, 会有匿名对象产生,用匿名对象对当前对象进行赋值,
	// 赋值完之后 匿名对象被释放
	// t2 = func();


	// Test1_1 &t3 = func();

	cout << "---------------------" << endl;
	return 0;
}

func()执行结果:
无参构造函数被调用
拷贝构造函数被调用
析构函数被调用
析构函数被调用
---------------------


 Test1_1 t = func()执行结果:
 无参构造函数被调用
拷贝构造函数被调用
析构函数被调用
---------------------
析构函数被调用



Test1_1 t2; 
t2 = func();
执行结果:
无参构造函数被调用
无参构造函数被调用
拷贝构造函数被调用
析构函数被调用
析构函数被调用
---------------------
析构函数被调用


 Test1_1 &t3 = func()执行结果:
无参构造函数被调用
拷贝构造函数被调用
析构函数被调用
---------------------
析构函数被调用

构造函数规则

1)当类中没有定义任何一个构造函数时,c++编译器会提供默认无参构造函数和默认拷贝构造函数
2)当类中定义了拷贝构造函数时,c++编译器不会提供无参数构造函数
3)当类中定义了任意的非拷贝构造函数(即:当类中提供了有参构造函数或无参构造函数),c++编译器不会提供默认无参构造函数
4 )默认拷贝构造函数成员变量简单赋值
总结:只要你写了构造函数,那么你必须用。

构造析构阶段性总结
1)构造函数是C++中用于初始化对象状态的特殊函数
2)构造函数在对象创建时自动被调用
3)构造函数和普通成员函数都遵循重载规则
4)拷贝构造函数是对象正确初始化的重要保证
5)必要的时候,必须手工编写拷贝构造函数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值