按值传递对象剖析

      在传递变量时,按值传递变量、按地址传递和按指针传递差别不是很大,但是如果传递的是对象时,三者的差别很大。

    这是因为,按值传递在向函数传递一个对象时,会像传递变量那样在外部函数内建立一个该对象的拷贝,而从函数返回一个对象时,也要建立这个被返回的对象的一个拷贝

    假如该对象的数据非常多时,这种拷贝带来的内存开销是相当可观的。比如说,该对象拥有1000多个double型成员变量,每个double型变量占据8个字节,1000个就要占据8000个字节,每次通过值传递的方式给函数传递该对象,都要在中复制该对象,占用8000个字节的栈内存,而返回该对象,又要在栈中复制一次,这样就又要占用8000个字节的内存空间。我们知道,栈的内存只有2M大小,8000个字节占用8K,那么仅仅传递该对象就占用了栈内16k字节的空间。并且别的对象想要访问该对象的8000个数据成员的时候,也要同样采取复制的方式,那么系统的开销将无法估算了。

    然而,按值传递所付出的开销远不止如此,由于在传递过程中需要复制对象,因此会默认调用复制构造函数,该函数的作用就是创建某个对象的临时副本。

    而当函数返回时,传递该对象时创建的该对象的副本会被删除,这时候又会自动调用该对象的析构函数来释放内存。假设返回的仍然是该对象,并且仍旧采用按值传递的方式,那么就又会调用复制构造函数建立一个该对象的临时副本,当该值被成功返回给调用程序后,然后再调用该对象的析构函数删除临时拷贝,并释放内存。

代码如下:

#include <iostream>
using namespace std;
class A
{
public:
 A(){cout<<"构造函数被调用..."<<endl;}
 A(A&){cout<<"复制构造函数被调用。。。"<<endl;} //复制构造函数
 ~A(){cout<<"析构函数被调用..."<<endl;}
};
A func(A one)
{
 return one;
}
int main()
{
 A a;
 func(a);
 return 0;
}

运行结果如下:

构造函数被调用...
复制构造函数被调用。。。
复制构造函数被调用。。。
析构函数被调用...
析构函数被调用...
析构函数被调用...

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值