C++是一门面向对象(OOP)编程语言,在这门语言中也有函数,函数的参数可以是变量数值,当然也可以是对象。所以,传统地就有关于对象是按值传递还是按址传递的讨论。

在C语言中,按值传递在很多情况下可以出色地完成任务,而且也很好理解,但是在C++中,因为有了类的对象这个可能的庞然大物(指他的数据特别大),如果还用传值的方式进行的话,会很浪费内存空间。本文就具体讨论这个问题。

在C++中,将一个对象按值传递时,会默认调用一个复制构造函数做一个这个参数的副本给函数。默认的复制构造函数名字是:类名(类名&)。请看下面代码:

#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 (void)
{
A a;
func(a); return 0;
}

这里的执行结果是:

这里我们发现执行了一次构造函数,两次复制构造函数,三次析构函数,结果很有意思,现在分析如下:

第一次只执行构造函数是因为新建了A类的对象a,因此调用构造函数来构造对象,当main函数调用func函数的时候,将对象a的值传给了func函数,这个时候就要调用复制构造函数来做一个对象a的副本,当func函数执行完毕时,要将对象one返回,这个时候还要调用复制构造函数来做一个one对象的副本,然后调用析构函数释放func函数中的对象one,当回到main函数中的时候,由于返回的one对象没有使用,所以这个时候又要调用析构函数来释放这个返回的对象,当main函数执行完毕时,a对象的也该释放了,这个时候就要调用类的析构函数来释放a对象的空间。从上面的分析中我们看出这个过程中,有很多次调用,每次调用都要进行对象的复制,既浪费了内存,有降低了程序的执行效率。该怎么优化呢?这个时候我们可以使用传址的方式来进行,将代码修改如下:

#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 (void)
{
A a;
func(&a); return 0;
}

可以看到这里将传参的方式修改成了按址的方式,他的执行结果如下:

这里减少了一次复制构造函数和析构函数的调用,可以理解效率明显提高,但是要注意的是这里还有一对复制构造函数和析构函数的调用,这是为什么呢?仔细观察可以发现,func函数返回的是(*one),这是一个对象,而不是地址,所以他要调用复制构造函数来创建一个对象的副本,然后在析构。如果我们把func函数的返回类型修改为指针类型的时候就可以减少调用了:

#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 (void)
{
A a;
func(&a); return 0;
}

这样,执行的结果就是:

这样就达到了对对象作为参数传递程序的最佳优化效果了!

最新文章

  1. iOS集成sharesdk遇到的坑
  2. 深入C#内存管理来分析值类型&amp;引用类型,装箱&amp;拆箱,堆栈几个概念组合之间的区别
  3. [lua大坑]一个莫名其妙的lua执行时崩溃引出的堆栈大小问题
  4. Bloom Filter学习
  5. 孙鑫MFC学习笔记16:异步套接字
  6. System V IPC(2)-信号量
  7. 玩转Windows Azure存储服务——网盘
  8. .Net 三款工作流引擎比较:WWF、netBPM 和 ccflow
  9. 在Swift中使用libxml2
  10. C#(WinForm)上传图片保存到数据库和从数据库读取图片显示到窗体
  11. tomcat中的URL参数为中文,servlet接收后显示乱码
  12. 在qt中用tcp传输xml消息
  13. LaTeX入门教程(二)
  14. react-router 中的history(react中关于后退键的处理用的到)
  15. Administrator账户密码忘了怎么办
  16. Struts存取数据
  17. BZOJ2681 : 玩游戏2
  18. 用gulp-imageisux智图api压缩图片
  19. Git 常用命令整理(转)
  20. (53)Wangdao.com第七天_JavaScript 强制类型转换

热门文章

  1. Hive集成HBase详解
  2. Python源码学习之初始化(三)-PyDictObject的初始化
  3. 基于注解的Spring MVC
  4. CSS元素 之 float
  5. (转)android客户端从服务器端获取json数据并解析的实现代码
  6. 作为java应届生,面试求职那点事
  7. Linux设置日期
  8. java HashMap的原理
  9. 点击推送消息跳转处理(iOS)
  10. hdu Red and Black