跟我学C++中级篇——处理对象的复制
一、对象的传递
在应用程序中,经常会遇到不同线程或不同模块间需要进行对象的传递,本来传递不是什么多大的事。但问题是,如果对象的值大到一定的程度后,传递不是问题可对象值的处理反而成了问题了。举一个现实世界的例子,用人传递物品,如果是一个水果,一个手机之类的简单东西,那么几乎不会耗费什么精力和时间。但如果让人代传一吨水果,一车手机怎么办?传递本身不是主要的了,主要的是货物如何进行运输了。
而在计算机世界中,对象的传递也是如此,大对象的处理就成为了一个主要的问题。
二、类对象的拷贝
几乎在所有的学习C++编程的开发者中,都接触过类的拷贝过程中的深拷贝和浅拷贝的问题。这也是在面试过程中,让面试者编写string类的一个面试点。而通过这个面试点,则可引出类的拷贝问题,包括拷贝构造函数、拷贝赋值函数,当然C++11后也包括移动构造函数、移动构造函数和移动赋值函数。这也就是前面的文章中提到的“三五法则”(本文不谈论拷贝函数等的具体实现,也不对三五法则进行展开分析,有兴趣的可以参看前面的相关内容。)。
对象的拷贝,其实就是如何正确处理对象内容特别是数据的拷贝,如果涉及到对象内部的对象变量则也可以如此认为。
三、内存的拷贝
在参数的传递过程中,除了有对象的拷贝,还有数组等的传递,如果把它们都当成对象的话,则可以统一到对象的拷贝或者说大对象的拷贝。大对象的拷贝,本质其实就是内存的拷贝,无论是在堆上还是栈上,原理基本都是一样的,所谓大对象其实就是内存占用的多罢了。
既然明白了对象和内存拷贝最终其实是一致的后,就会明白了如何对对象传递的优化。
四、常见的优化手段
对象或内存的优化手段常见的有如下几种手段或者说方法:
1、使用C++标准中的方法
1)引用或指针传递:这种比较简单,也是开发者经常使用的,不过需要注意与const的配合使用
2)使用移动语义:这个只能是在C++11标准后,其它倒没什么
2、借助编译器的优化
1)返回值优化(RVO或NRVO):这个在前面分析过,大家也可以查看相关的资料
2)尾调优化(TCO):这个才刚刚分析过,有兴趣可以看一下
3、使用库或框架
1)使用类似于STL中的std::swap方法
2) 使用类似于对象池或内存池的方法或手段
4、使用一些策略
比较常见的就是COW,写时复制、零拷贝等。前面反复分析过,此处不再展开。
上面的手段后,有的是可以避免内存的复制的方法,有的则是一种优化的策略,特别是对COW这种,其实就是一种平衡的手段。另外,零拷贝则是一种优化的抽象,具体到不同的具体场景可能是有所不同的。
五、总结
本文可以说是对前面的一系列的相关文章的总结,如果只是看这一篇,可能有务虚的感觉。大家可以把本文做为一篇阅读的目录或大纲,逐一展开去学习或分析即可。当然,不是每个开发者对这些内容都感兴趣,大家只要根据自己情况决定即可。