c++的构造函数

本文详细介绍了C++中的构造函数,包括无参构造函数、有参构造函数及其调用方式,赋值构造函数的作用及四种调用场景,并特别讨论了匿名对象在不同情况下的行为。此外,还提到了析构函数的自动调用和作用,以及浅拷贝问题与深拷贝的解决方案。

c++的类中包含以下三种构造函数:
1.无参的构造函数 : 类名()
2.有参的构造函数 : 类名(形参)
有参构造函数的三种调用方法:2.1 括号法
2.2 等号法
2.3 手动的调用构造函数
3.赋值构造函数 (作用:用一个对象初始化另外一个对象): 类名(const 类名& obj)
赋值构造函数四种调用场景: 3.1 用一个对象去初始化另外一个对象(使用等号)
3.2 用一个对象去初始化另外一个对象(使用括号)
3.3 将实参对象传递给形参对象元素
3.4 函数的返回值是一个对象元素(函数的返回值是一个元素 , 返回的是一个新的匿名对象(所以会调用匿名对象类的copy构造函数))
匿名对象的不同接收情况会产生不同的情况:如果用匿名对象 初始化 另外一个同类型的对象, 匿名对象 转成有名对象
如果用匿名对象 赋值给 另外一个同类型的对象, 匿名对象 被析构
如果匿名对象 没有接受的对象, 匿名对象 被析构

析构函数:~类名() //析构函数是自动调用,作用是当对象结束生命周期时来释放释放对象的内存
注意:C++编译器提供的默认copy构造函数和=号操作符都是浅拷贝(解决浅拷贝的办法就是自己写一个copy函数作为深拷贝)

#include "iostream"
using namespace std;
class Test
{
public:
	//1.无参的构造函数
	Test()
	{
		cout << "无参的构造函数" << endl;
	}
public:
	//2.有参的构造函数
	Test(int a)
	{
		m_a = a;
		cout << "Japanes m_a=" << m_a << endl;
	}
	Test(int a,int b)
	{
		m_a = a;
		m_b = b;
		cout << "有参的构造函数 m_a"<< m_a<<"m_b "<< m_b << endl;
	}
	//3.赋值构造函数 (copy构造函数)(后续再讲)
	Test(const Test& obj)
	{
		cout << "赋值构造函数" << endl;
	}
public:
	void printT()
	{
		cout << "普通成员函数" << endl;
	}
	~Test()
	{
		//析构函数
	}
private:
	int m_a;
	int m_b;
};
void main()
{
	//1.无参的构造函数调用方法
	Test t1;//无参的构造函数调用方法,直接用类名定义一个无括号的对象即可。
	
	//有参数的构造函数的三种调用方法
	//2.1 括号法
	Test t2(1,2);//调用参数构造函数  c++编译器自动的调用构造函数
	t2.printT();//对象仍然可以调用普通成员函数

	// 2.2 等号法  //调用参数构造函数  c++编译器自动的调用构造函数
	Test t3 = (3, 4,5,6);//等号法只能调用起一个参数,不管括号里面有几个参数,只有最后一个数有用,相当于直接对其赋值最后一个数,如下
	Test t4 = 5;

	//2.3 手动的调用构造函数
	Test t5 = Test(7, 8);//对象初始化,这里的调用方法其实是对t5对象的初始化,整个过程也只有一次调用构造函数。其实就相当于Test t5=t2;


	//赋值操作 
	t2 = t5;//把t5 copy给 t2  (浅拷贝,会出现同一个内存地址被两个对象调用,但是其中一个对象析构之后,另外一个对象再调用这一块内存地址就会出现问题)
			//对象的初始化 和 对象的赋值 是两个不同的概念 
	system("pause");
}

copy函数的四种调用场景

#include <iostream>
using namespace std;
class Test1
{
public://无参数构造函数
	Test1()  
	{
		m_a = 0;m_b = 0;
		cout << "m_a=" << m_a << "m_b" << m_b << endl;
		cout << "无参数构造函数" << endl;
	}
public://有参数构造函数
	Test1(int a)
	{
		m_a = a;m_b = 0;
		cout << "m_a=" << m_a << "m_b" << m_b << endl;
	}
	Test1(int a, int b) 
	{
		m_a = a;m_b = b;
		cout << "m_a=" << m_a << "m_b" << m_b << endl;
		cout << "有参数构造函数" << endl;
	}
public://赋值构造函数 (copy构造函数)//作用:用一个对象初始化另外一个对象
	Test1(const Test1& obj)
	{
		cout << "我也是构造函数 " << endl;
		m_b = obj.m_b + 100;
		m_a = obj.m_a + 100;
		cout << "m_a=" << m_a << "m_b" << m_b << endl;
	}
	~Test1()
  	{
		cout << "我是析构函数 " << endl;
		cout << "m_a=" << m_a << "m_b" << m_b << endl;
	}
public://普通成员函数
	void printT()
	{
		cout << "普通成员函数" << endl;
		cout << "m_a" << m_a << " m_a" << m_b << endl;
	}
private:
	int m_a;
	int m_b;
};
//3.1 copy构造函数第一种调用方法 用一个对象去初始化另外一个对象(使用等号)
void main04()
{
	Test1 t0(1,2);
	Test1 t1(3,4);
	//赋值操作,并不会调用copy构造函数
	t0 = t1;//用t1给t0赋值操作 和 初始化是两个不同的概念(赋值不会调用构造函数)(C++编译器提供的等号操作属于浅拷贝)
	//3.1 copy构造函数 用一个对象去初始化另外一个对象
	Test1 t2 = t1;//这是初始化,不是赋值(C++编译器提供的默认copy构造函数也是浅拷贝)
}
//3.2 copy构造函数第二种调用方法 用一个对象去初始化另外一个对象(使用括号)
void main05()
{
	Test1 t0(1, 2);
	Test1 t1(t0);//先析构t1再析构t0
}
//3.3 copy构造函数第三种调用方法 将实参对象传递给形参对象元素
//业务函数  形参是一个元素
void function(Test1 t)
{
	t.printT();
}
void main06()
{
	Test1 t0(1, 2);//调用有参数的构造函数
	function(t0);//t0实参 初始化形参t,会调用copy构造函数(t0--copy-->t)
 }
//3.4赋值构造函数第四种调用方法 函数的返回值是一个对象元素
//当function1函数 返回一个元素时有如下两个结论
//结论1 : 函数的返回值是一个元素 (复杂类型的), 返回的是一个新的匿名对象(所以会调用匿名对象类的copy构造函数)

//结论2: 有关 匿名对象的去和留
//如果用匿名对象  初始化 另外一个同类型的对象, 匿名对象 转成有名对象
//如果用匿名对象  赋值给 另外一个同类型的对象, 匿名对象 被析构
//如果匿名对象              没有接受的对象,   匿名对象 被析构
Test1 function1()//返回的是一个匿名对象(匿名对象保存在内存区中,而t0对象被析构)
{
	Test1 t0(1, 2);
	return t0;//调用copy构造函数,复制给一个匿名函数
}
void main07()
{
	//用匿名对象初始化t1 此时c++编译器 直接把匿名对转成t1;(扶正) 从匿名转成有名字了t1
	Test1 t1 = function1();//因为是将匿名对象  初始化  给元素t1,匿名对象不会被析构而是直接被扶正为t1
	t1.printT();

	Test1 t2(3, 4);
	t2 = function1();//用匿名对象  赋值  给m2后, 匿名对象被析构
	t2.printT();

	function1();//匿名对象没有接收的对象,会直接被析构掉
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值