020_拷贝构造函数的四种调用时机

/*
	copy构造函数的调用  时机1 时机2
*/

#if 1
class Test4
{
public:
	Test4()  //无参数构造函数
	{
		m_a = 0;
		m_b = 0;
		cout << "我是构造函数,自动被调用了" << endl;
	}

	Test4(int a)
	{
		m_a = a;
		m_b = 0;
	}

	Test4(int a, int b) //有参数构造函数   //3种方法
	{
		m_a = a;
		m_b = b;
		cout << "有参数构造函数" << endl;
	}

	//赋值构造函数 (copy构造函数)  作用完成对象的初始化
	Test4(const Test4& obj)
	{
		cout << "我也是构造函数,我是通过另一个对象obj来初始化我自己 " << endl;
		m_a = obj.m_a + 100;
		m_b = obj.m_b + 100;
	}


	~Test4()
	{
		cout << "我是析构函数,自动被调用了" << endl;
	}

public:
	void printT()
	{
		cout << "普通成员函数" << endl;
		cout << "m_a = " << m_a << ", m_b = " << m_b << endl;
	}

private:
	int m_a;
	int m_b;

};

void test()
{
	//赋值构造函数 用一个对象初始化另一个对象
	Test4 t1(10, 12);
	Test4 t0(0, 2);

	//赋值操作 和 初始化是两个不同的概念

	//赋值 = 操作  不会调用拷贝构造函数,编译器给我们提供的浅copy
	t0 = t1;		//用t1 给 t0赋值    

	//第一种 调用拷贝构造函数的时机
	Test4 t2 = t1;	//用t1来初始化t2,调用t2这个对象的拷贝构造函数
	t2.printT();

	//第二种 调用拷贝构造函数的时机
	Test4 t3(t1);	//用t1来初始化t2
	t3.printT();
}

#endif

这里写图片描述

/*
	赋值构造函数的调用  时机3
	*/
#if 1
class Location
{
public:
	//构造函数
	Location(int xx = 0, int yy = 0)
	{
		X = xx;
		Y = yy;
		cout << "Constructor Object." << endl;
	}
	//拷贝构造函数  完成对象的初始化
	Location(const Location &obj)
	{
		X = obj.X;
		Y = obj.Y;
		cout << "copy 构造函数." << endl;
	}

	~Location()
	{
		cout << X << "," << Y << " Object destroyed." << endl;

	}
	int GetX()
	{
		return X;
	}
	int GetY()
	{
		return Y;
	}
private:
	int X, Y;
};

//第三种 调用拷贝构造函数的时机
void f(Location p)	//参数是一个元素
{
	cout << p.GetX() << endl;
}

void test()
{
	Location a(1, 2);
	Location b = a;		//第一种 调用拷贝构造函数的时机
	/*
		实参b去初始化形参p,c++编译器会调用形参 p 这个对象的copy构造函数,
		由于p是局部变量,函数f()运行完毕,p对象的生命周期结束,会调用
		p对象的析构函数。

		先创建的对象后释放
	*/
	//b实参去初始化形参p,会调用copy构造函数 
	cout << "-------1------" << endl;
	f(b);			//第3种时机
	cout << "-------2------" << endl;
	cout << "b对象已经初始化完毕" << endl;

}
#endif

这里写图片描述

/*
	赋值构造函数的调用  时机4
*/
#if 1
class Location
{
public:
	//构造函数
	Location(int xx = 0, int yy = 0)
	{
		X = xx;
		Y = yy;
		cout << "Constructor Object." << endl;
	}
	//拷贝构造函数  完成对象的初始化
	Location(const Location &obj)
	{
		X = obj.X;
		Y = obj.Y;
		cout << "copy Constructor Object." << endl;
	}

	~Location()
	{
		cout << X << "," << Y << " Object destroyed." << endl;

	}
	int  GetX() { return X; }		int GetY() { return Y; }
private:
	int X, Y;
};

//第4种 调用拷贝构造函数的时机
Location g()
{
	Location A(11, 22);//执行对象A的构造函数
	return A;
	/*
	return A;
	这条语句  首先会创建一个匿名对象,用对象A初始化匿名对象,执行匿名对象的copy构造函数,
	然后对象A的生命周期结束了,会执行对象A的析构函数。g()返回一个匿名对象.
	*/
}

//测试匿名对象的生命周期
void objplay2()
{
	g();//g()返回一个匿名对象,如果匿名对象没人接,则会执行匿名对象的析构函数。
}



运行结果(测试匿名对象的生命周期)
这里写图片描述

/*
g()函数 返回一个元素
结论 1:函数的返回值是一个元素(复杂类型的),返回一个新的匿名对象(所以会调用匿名对象
的 copy构造函数)。
结论 2:有关匿名对象的去和留
如果用匿名对象 初始化 另一个同类型的对象,匿名对象转化为有名对象,匿名对象不会被析构掉
如果用匿名对象 赋值给 另一个同类型的对象,匿名对象被析构
*/


void objplay3()
{
	//用匿名对象初始化m,此时c++编译器直接把匿名对象转成m(扶正),从匿名转成有名对象了m
	Location m = g();
	printf("匿名对象,被扶正,不会被析构掉\n");
	cout << m.GetX() << endl;
}

运行结果(函数返回的匿名对象的去初始化另一个对象)
这里写图片描述

在这里插入图片描述

void objplay4()
{
	Location m2(1, 2);
	m2 = g();//用匿名对象 赋值给 m2
	printf("因为用 匿名对象 赋值 给m2, 匿名对象被析构\n");
	cout << m2.GetX() << endl;
}

运行结果(函数返回的匿名对象的去赋值另一个对象)
这里写图片描述

void objplay5()
{
	//用匿名对象 赋值给 m2
	Location m1(1, 2);
	cout << "------1-----" << endl;
	m1 = Location(33, 44);  //赋值操作   Location(33, 44)会产生匿名对象,匿名对象被析构
	cout << "------2-----" << endl;
	Location m2 = Location(55, 66);//初始化操作 Location(55, 66)会产生匿名对象,匿名对象转正,不会被析构
	cout << "------3-----" << endl;
}

运行结果:
这里写图片描述

void objplay6()
{
	Location(77, 88);  //直接调用构造函数,会产生匿名对象,临时匿名对象的生命周期  
	cout << "------1-----" << endl;
}

这里写图片描述

void test()
{
	//objplay2();
	//objplay3();
	//objplay4();
	//objplay5();
	objplay6();

}
#endif
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值