2009-10-05 138 views
5

[EDIT 1 - 加入第三指針語法(感謝亞歷克斯)]C++ DAL - 返回參考或填充傳入參考

您喜歡哪方法,用於一DAL和爲什麼會出:

Car& DAL::loadCar(int id) {} 
bool DAL::loadCar(int id, Car& car) {} 
Car* DAL::loadCar(int id) {} 

如果無法找到汽車的第一個方法返回null,則第二個方法返回false。

第二種方法會在堆上創建一個Car對象,並填充從數據庫查詢的數據。據推測(我的C++是非常生鏽),這將意味着沿行代碼:

Car& DAL::loadCar(int id) 
{ 
    Car *carPtr = new Car(); 
    Car &car= *carPtr; 
    car.setModel(/* value from database */); 
    car.setEngineSize(/* value from database */); 
    // etc 
    return car; 
} 

由於

回答

5

第二絕對優選的。你正在返回一個對已經被new'd對象的引用。對於使用該軟件的最終用戶來說,返回的對象需要刪除並不明顯。 PLUS如果用戶做了這樣的事情

Car myCar = dal.loadCar(id); 

指針會丟失。

因此,您的第二種方法將控制內存放在調用者上,並停止發生任何奇怪的錯誤。

編輯:通過引用返回是明智的,但只有當父級(即DAL)類可以控制引用的生存期時。即如果DAL類有一個Car對象的向量,那麼返回一個引用將是一個非常明智的事情。

編輯2:我還是喜歡第二個設置。第三個比第一個好得多,但你最終使得調用者假定對象被初始化。

你也可以提供

Car DAL::loadCar(int id); 

並希望接受的堆棧副本。

另外不要忘記,你可以創建一種空汽車對象,這樣你就可以返回一個「有效」的ish對象,但是在所有的字段中沒有返回任何有用的信息(因此顯然被初始化爲垃圾數據)。這是空對象模式。

+0

謝謝。即使調用者寫了「Car&myCar = dal.loadCar(id)」,指針也不會丟失?無論如何,非DAL代碼可以刪除由DAL創建的內存嗎? – ng5000 2009-10-05 13:37:00

+0

如果調用者寫下你剛寫入的內容「可以」已經釋放,否則不需要。你需要調用「刪除&myCar;」來做到這一點,雖然..這看起來很奇怪。 – Goz 2009-10-05 14:07:19

+0

棧拷貝甚至可能不會發生:根據編譯器和優化,(N)RVO可能會啓動並使操作等同於#1。無論如何,當汽車沒有找到時拋出異常是必要的。 – 2009-10-05 14:45:48

4

由於您無論如何都在堆上分配對象,爲什麼不考慮Car * LoadCar(),如果發生問題,它將返回NULL。這樣,您對引用類型沒有限制(每個引用必須被初始化),並且還有手段來指示錯誤情況。

+0

聽起來合理,更新的問題添加第三個選項。 – ng5000 2009-10-05 13:39:27

+0

Car&DAL :: loadCar(int id)不能返回NULL;沒有空引用,只有空指針。 – Massa 2009-10-05 16:56:09