探究C++返回值为对象时拷贝构造函数的调用机制

前段时间学习C++,拷贝构造函数在三个时机会被调用,函数传参,新建对象,函数返回

函数返回时是怎么操作的呢,由于C语言没有this指针,所以我们借着C++的this指针可以打印出一些信息,顺便也可以猜测C语言的函数返回时是怎么搞的

【注意】:

在编译时关闭RVO,RVO优化关闭,可以对g++增加选项-fno-elide-constructors

root@ubuntu:/lianxi/lianxi_c++/chapter9# g++ -fno-elide-constructors returnTest.cpp 
root@ubuntu:/lianxi/lianxi_c++/chapter9# ./a.out
=====TEST START=====
call TestFunc
call default constructor, this = 0xbfd8d77c
&testBox = 0xbfd8d77c
call copy constructor, this = 0xbfd8d7ac
&copySrc = 0xbfd8d77c
call destroyer, this = 0xbfd8d77c
call copy constructor, this = 0xbfd8d7a8
&copySrc = 0xbfd8d7ac
call destroyer, this = 0xbfd8d7ac
&mainBox = 0xbfd8d7a8
call getData, this = 0xbfd8d7a8
this->data = 0
=====TEST END=====
call destroyer, this = 0xbfd8d7a8
root@ubuntu:/lianxi/lianxi_c++/chapter9# 
#include <iostream>
#include <string>
#include <stdio.h>

class BOX
{
	private:
		int data;
	public:
		/*default constructor*/
		BOX(int initData = 0) : data(initData)
		{
			std::cout << "call default constructor, this = " << this << std::endl;
		}

		/*copy constructor*/
		BOX(const BOX& copySrc)
		{
			std::cout << "call copy constructor, this = " << this << std::endl;
			printf("&copySrc = %p\n", &copySrc);
			this->data = copySrc.data;
		}

		/*destroyer*/
		~BOX(void)
		{
			std::cout << "call destroyer, this = " << this << std::endl;
		}

		/*memberFunc*/
		void getData(void)
		{
			std::cout << "call getData, this = " << this << std::endl;
			std::cout << "this->data = " << this->data << std::endl;
			return;
		}
};

BOX TestFunc(void)
{
	std::cout << "call TestFunc" << std::endl;
	BOX testBox;
	printf("&testBox = %p\n", &testBox);
	return (testBox);
}

int main(void)
{
	printf("=====TEST START=====\n");
	BOX mainBox = TestFunc();
	printf("&mainBox = %p\n", &mainBox);
	mainBox.getData();
	printf("=====TEST END=====\n");
	return (0);
}

-------------------------------------------CUT LINE----------------------------------------------

整个过程分析如下:

(1)=====TEST START=====

(2)调用TestFunc,打印call TestFunc

创建对象testBox,调用其默认构造函数,我们可以看到&testBox == 0xbfd8d77c

从printf打印也可以看出这点

(3)执行return语句

这时创建了一个临时BOX的对象,没有名字,我们暂且叫它temp

调用temp的拷贝构造函数,&temp == 0xbfd8d7ac,而copySrc就是testBox

拷贝构造函数完成后temp也创建完成,调用testBox的析构函数,整个TestFunc退栈

(4)返回到TestFunc函数调用处,创建mainBox对象,调用其拷贝构造函数

&mainBox == 0xbfd8d7a8,而copySrc就是temp

拷贝构造函数完成后mainBox创建完成,调用temp的析构函数,临时对象不再使用

(5)调用mainBox的成员函数,data成员值为0

=====TEST END=====

main函数结束,调用mainBox的析构函数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值