1. 引用作為參數的方式傳遞.
1 GetObject(Object& obj) 2 { 3 obj.value = value1; 4 }
特點: 在外部構造一個對象. 把該對象以引用的方式傳遞到函數中. 從而實現對該對象的改變, 該參數實質是一個[out]類型的參數, 而非[in]類型的參數. 這里的引用可以稱為別名.
點評: 這種方式需要特別的注釋參數是[Out]還是[In]類型, 防止無用. 另外用Get這樣的名稱, 一般都是指存在返回值的. 這樣會存在理解和溝通的問題. 需要特別注釋.
這種方式很值得推薦, 因為函數沒有分配內存. 不會涉及到內存的釋放操作, 很安全.
2. 用指針的方式, 傳遞參數,
1 GetObject(Object* obj) 2 { 3 obj->value = value1; 4 }
這個方式跟上面的方式完全一致. 指針跟引用(別名)是指上是一個相同的方式. 是指上所指的都是相同的內存區域.
點評: 同1.
3. 函數內部, 在Heap中構造一個對象, 並在外面返回該對象的指針.
1 Object* GetObject() 2 { 3 Object *a = new Object(); 4 return a; 5 }
點評: 既然在Heap中構造了一個對象, 准備在哪里將其釋放? 是個問題.
這里非常容易造成內存泄漏的, 因為內存分配和釋放的原則是: 哪里分配, 就在哪里釋放, 顯然這里是滿足不了要求的.
當然, 上述原則並不絕對(跨模塊調用的話, 強烈建議堅持該原則.)
4. 以返回值的方式, 直接返回一個對象.
1 Object GetObject() 2 { 3 Object a; 4 return a; 5 }
點評: a對象會復制一份, 交給返回值.
這樣造成的問題是, 需要提供copy構造函數, 否則會出大問題的.
另外, 對象的復制, 進行了大量的工作, 將導致效率下降, 同事棧的空間也被占用. 代價還是比較高昂.
//附加一些容易犯的錯誤.
問題1: 下面的例子的問題是, a對象離開作用域(函數)時, 將可能被自動釋放, 造成指針指向的位置被清理的問題.
1 Object * GetObject() 2 { 3 Object a; 4 return &a; 5 }
問題2: 下面的例子, 不但造成了內存泄漏, 並且*a所指的對象仍然被復制了一份. 即引發了效率低下, 以及內存泄漏兩個問題.
1 Object GetObject() 2 { 3 Object *a = new Object(); 4 return *a; 5 }