C++11如何减少内存拷贝次数
C++11中出現了很多迷人的特性。例如智能指針實現高效的內存管理,std::bind和std::function函數封裝器,以及lambda實現的函數對象語法糖,都是使我著迷的地方。
而C++11最大的改動則是移動語義,考慮這么一個場景:將一個將亡對象A的內容拷貝給另一個對象B,然后A對象被析構釋放內存,我們的程序使用B對象。這是經常發生的事情,調用函數傳參或者函數返回值時最為常見。如果A和B對象占用的內存非常多,則這個操作會導致大量內存的拷貝。
為什么我們不直接將對象A的名字改成B呢?這樣就省去了拷貝內存和析構的時間,增加的只是重命名的時間,在對象所占內存巨大時(例如對象是一個高度為1000的平衡二叉樹(std::map),每個節點又是一個龐大的自定義結構體)。
是的,為了這個目的,C++作出了很多的努力,引用傳參就能實現為對象取一個別名的作用,然而這一套別名系統必須保證原對象存在,如果原對象超出作用域被析構,則所有關于這個對象的別名都會立刻失效,這一個對象的持有者還是它自身,只是使用別名可以在對象存在期間引用它。
想要改變持有者,則可以使用智能指針,多個指針同時持有一個對象,當最后一個指針析構時會將指向的對象析構,這使得對象可以被多個指針持有,這是智能指針與引用語法的一個區別,并且智能指針是靠庫實現,而引用是靠語法支持。而智能指針有一個非常大的特點,它有權力析構對象,意味著它所指向的內容必須是堆區內容,而棧上的內容則靠出棧時自動析構釋放內存,如果你的大體積的對象是放在棧上,則使用智能指針是不行的。
移動語義的發明,就能解決這個問題,不管發生棧上或者堆上 大體積對象的拷貝,就可以使用移動語義,改變該對象的持有者,而不需要拷貝這塊內存。還是最初 將亡值A拷貝到B的例子,依靠移動語義,拷貝時使B指向A的內容,然后A指向B的內容(也就是交換內容,注意這里的交換沒有發生大內存拷貝,只是改變了指針的指向。)然后A對象釋放,我們接著使用B對象,B對象的內容是A原來的內容,而A對象析構時將B對象原本要被覆蓋的內容析構掉,完美。
C++從引用語法、智能指針類、移動語義多個方面支持開發者減少內存的拷貝,發揮出C++的性能威力。在設計良好的情況下,不會出現大內存塊的拷貝。
?
轉載于:https://www.cnblogs.com/xjjsk/p/8952139.html
總結
以上是生活随笔為你收集整理的C++11如何减少内存拷贝次数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unity3d 控制物体移动、旋转、缩放
- 下一篇: Java 虚拟机导论:什么是 Java虚