------------------------------------------------------------
author: hjjdebug
date: 2024年 09月 10日 星期二 11:02:55 CST
descrition: 对象作为函数参数及对象作为返回值的工作过程
------------------------------------------------------------
问: 类对象做为函数参数是怎样工作的?
答: 对象作为函数参数是值copy, 会在栈上构建对象.然后调用子函数,函数操作的是栈上的临时对象.
问: 类对象做为函数返回值是怎样工作的?
答: 必不可少的会有一次赋值构造(=),
很可能还跟着2次copy构造,
一次是函数return了对象,return到何方? return 到赋值构造的源(=号的右值).
另一次是赋值构造(=)也会return对象,对象的目标肯定是return到=号的左值,
验证:
源代码:
#include <iostream>
using namespace std;
class Square //正方形
{
public:
Square():_len(0){cout<<"in default construct"<<endl;} //默认构造函数
Square(int len) :_len(len) {cout<<"in param construct"<<endl;} //带参构造函数
Square(const Square &a) {cout <<"in copy construct. arg addr:"<<&a<<endl; _len=a._len;} //拷贝构造函数
Square operator=(Square ); //赋值构造函数
int area(); //输出面积
int _len;//边长
};
int Square::area() //输出面积
{
return _len * _len;
}
Square Square::operator=(Square a)
{
cout<<"in assign construct. arg addr:"<<&a<<endl;
_len=a._len;
//会调用拷贝构造
return *this;
}
//参数是对象, 会调用copy 构造在栈上构建临时对象
//对临时对象的修改对实参没有影响
Square Add(Square a)
{
cout<<"in Add, a addr:"<< &a<<endl;
a._len++;
return a;
}
int main()
{
Square s1(2); //带参构造函数
Square s2; //默认构造函数
cout<<"in main, s1 addr:"<< &s1<<endl;
cout << "函数调用前," << "s1:"<<s1.area()<<" s2:"<<s2.area()<<endl;
//传参会调用copy construct构建临时参数对象a
//=会调用赋值构造
s2=Add(s1);
cout << "函数调用后," << "s1:"<<s1.area()<<" s2:"<<s2.area()<<endl;
return 0;
}
执行结果:
hjj@hjj-7090:~/test/tt$ ./tt
in param construct //s1 的带参构造
in default construct //s2 默认构造函数
in main, s1 addr:0x7ffda5c8c564 // main 函数打印
函数调用前,s1:4 s2:0 // main 打印
in copy construct. arg addr:0x7ffda5c8c564 //传递到Add 函数参数a ,其源就是s1
in Add, a addr:0x7ffda5c8c56c //Add 中参数地址是临时变量地址
in copy construct. arg addr:0x7ffda5c8c56c //Add 中返回a,其源是a,其目标是临时地址.
in assign construct. arg addr:0x7ffda5c8c570 //a中的临时目标地址作为assign 的源地址,assign的目标地址还是一个临时地址
in copy construct. arg addr:0x7ffda5c8c568 //assign的目标地址是copy的源地址,copy的目标地址是s2
函数调用后,s1:4 s2:9
对象传来传去肯定是浪费cpu资源的,所以说c++的效率比c的效率还是要差一些的.
如果gcc 做得很牛比, assign 是少不了的,它能够一端拿到a对像,另一端拿到s2对象,就省掉了2次copy构造,也许加上-O2就如此,我没有验证.
如果我们不传对象而是传对象指针或引用, 那自然效率就会高一些,
因为省去了对象考来考去的过程而直接传递的指针.
以上就是对 s2=Add(s1) 的详细的工作过程详细分析, 搞清它是怎样工作的还是有必要的.!