前段时间学习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
©Src = 0xbfd8d77c
call destroyer, this = 0xbfd8d77c
call copy constructor, this = 0xbfd8d7a8
©Src = 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("©Src = %p\n", ©Src);
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的析构函数