1. 程式人生 > >C++ 何時使用動態分配(即使用newkeyword)?何時使用指針?

C++ 何時使用動態分配(即使用newkeyword)?何時使用指針?

指向 delet 問題 con 擁有 才會 屬性 想要 自己

動態分配

在你的問題裏。你用了兩種方式創建對象。這兩種方式基本的不同在於對象的存儲時間。

當運行Object myObject;這句代碼時。它作為自己主動變量被創建,這意味著當對象出了作用域時也會自己主動銷毀。而當你使用new Object()這樣的方式時,對象所擁有的內存是動態分配的。這表示直到你調用delete()方法對象才會被銷毀。否則一直存在。當須要用動態分配內存來處理時,你應該僅僅使用動態分配的方式,也就是說,當你能夠使用動態分配內存的時候就不要使用自己主動變量。

下面是可能會使用到動態分配的兩種常見情況:

1.當想讓對象在出了作用域後依舊存在——且確實就是之前存儲在該內存中的對象。而不是對象的拷貝。假設你能夠接受使用對象的拷貝或者移動(大部分情況下你應該這樣),那麽你更應該使用自己主動存儲方式。

2. 當須要大量內存時,這樣的情況下極易導致棧溢出。

當然假設這對你來說根本不是問題就更好了(大部分情況下這是不可能的)。這顯然超出了C++的管轄範圍,可是不幸的是,我們必須處理我們開發的系統中存在的這樣的現實問題。

當你確實須要使用動態分配時,你應該將它封裝到一個智能指針中或者其它能具有RAII特性的類型(比如標準容器)。智能指針提供動態分配內存的對象的全部權語義。比如std::unique_ptr和std::shared_ptr。

假設你可以合適的使用它,你基本上不須要自己管理內存(參見Rule of Zero這篇文章)。

指針

其實,指針除了用來實現動態分配內存外還有非常多其他的使用方法。可是當中大部分也都存在比它們更好的選擇。就像前面說過的那樣。除非你必須用到指針。否則不要貿然使用。

須要使用引用的情況:有的時候,你想調用的函數須要訪問你當前的對象本身(而不是它的拷貝)。那麽你就須要使用指針作為參數進行傳遞(暫不論它是怎樣分配的)。然而,在大部分情況下。使用引用會比指針更好,這也正是引用被設計的理由。註意一下,這裏不須要像上面所說的那樣去延長對象的生命周期。前面已經說過了,假設你能接受使用對象的拷貝。那麽你就不是必需再使用引用了。

須要使用多態的情況:通常你僅僅能通過對象的指針或者引用來實現多態(也就是依據對象的動態類型來調用函數)。假設這就是你想要的,那麽你就須要使用指針或者引用。相同,以指針為優先選擇。

當對象可忽略時,通過傳遞一個空指針來實現對象是可選的屬性:假設它是一個參數的話,你應該優先使用默認參數或者函數重載的方法。否則你應該選擇一種能夠封裝這樣的行為的類型,比如boost::optional(或者是std::optional)。

當你想減少文件間的編譯依存關系從而節省時間:指針的一大特點在於你僅僅須要在前面聲明一下指針指向的類型(而假設要使用實際的對象,你還須要定義一下)。

這樣你就能減少你的編譯單元之間的耦合性從而減少編譯時間。

參考Pimpl idiom.

當你想調用C或者類似C風格的函數庫的接口時:在這樣的情況下。你不得不使用指針進行操作。

你唯一能做的事情就是要保證你的指針在不使用時要被釋放。你也能通過智能指針來操作原指針,比如通過它來調用成員函數。

假設被調用庫已經為你申請了空間而又希望你通過句柄來釋放的話,利用智能指針封裝起句柄並利用定制的析構器來釋放內存無疑是一種合理的選擇。

C++ 何時使用動態分配(即使用newkeyword)?何時使用指針?