2009-10-09 300 views
0

全部,C++參考shared_ptr vs參考

我最近發佈了這個question DAL設計。由此看來,將一個對象的引用傳遞給一個函數,然後該函數將填充該對象,這對C++數據訪問層來說是一個很好的接口,

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

我現在想知道如果使用對boost :: shared_ptr的引用會更好,例如,

bool DAL::loadCar(int id, boost::shared_ptr<Car> &car) 

有什麼想法?一個人比另一個人有優勢嗎?

將const正確性應用於兩個調用的含義是什麼?

在此先感謝。

+0

什麼是loadCar應該做的? – sellibitze 2009-10-09 09:35:09

+0

「填充該對象」是什麼意思?我在下面的答案中假設「爲其賦值」有效的「值」。 – 2009-10-09 09:35:46

回答

3

As sbi說:「這取決於函數的功能。」

但是,我認爲上述最重要的方面不是NULL是否允許,但是函數是否存儲指向對象的指針使用。使用

  • ,功能仍然可以通過客戶誰不使用shared_ptr的,用於堆對象使用等
  • :如果功能只是一些數據填充,然後我會用基準,原因如下與shared_ptr的功能仍然是微不足道的 - 的shared_ptr具有對其操作返回參考
  • 傳遞null是不可能
  • 少打字
  • 我不喜歡使用「東西」時,我不必

如果函數需要存儲指針供以後使用,或者您預期函數可能會以需要存儲指針的方式進行更改,請使用shared_ptr。

0

在第一種情況下,您只需通過一輛汽車並用信息「填寫」。例如,您可以創建一個「默認」汽車,然後填寫它。我看到一個不便之處:擁有兩類汽車並不十分困難:一輛可憐的,默認的,無用的,「空的」汽車,一輛真正來自汽車的汽車。對我而言,一輛汽車是一輛汽車,所以它應該是一個有效的汽車(例如我可以從A地駕車到B地,例如我可以加速,制動,啓動,停止)。

我通常使用傳統的指針,而不是提升(順便說一句,沒有問題),所以我真的不能評論後者的選擇。

3

這取決於功能的作用。

一般來說,一個帶指針的函數指示調用者可能會調用這個函數,即使他們沒有對象傳遞給它 - 它們總是可以通過NULL。如果符合函數的規範,則使用(智能)指針。通過引用來計數智能指針而不是複製它們是一種優化(而不是過早的,我應該添加),因爲它避免了不必要地增加和減少引用計數,在MT環境中,引用計數可能會引起明顯的性能下降。

將非const引用作爲參數的函數期望傳遞一個可能更改的有效對象。調用者不能(合法地)調用該函數,除非他們有一個有效的對象,並且除非他們願意讓函數改變對象的狀態,否則他們不會調用它。如果這更符合功能的規格,請使用參考。

+0

該函數必須接收一個有效的對象,你不應該能夠傳遞NULL。 – ng5000 2009-10-09 09:49:10

+0

然後,一個對象的引用就是你想要的。無論引用是從一個對象,另一個引用,一個裸點還是一個智能指針初始化,都不應該影響該函數本身。 – sbi 2009-10-09 12:29:04

1

如果您必須收到一個有效的對象(即您不希望調用者傳遞NULL),那麼請不要使用boost :: shared_ptr。你的第二個例子傳遞了一個「智能指針」的引用......忽略細節,它是一個「指向汽車指針的指針」。因爲它是引用,所以shared_ptr對象不能爲NULL ....但並不意味着它不能有NULL值(即指向「空」對象)。

我不明白爲什麼你會認爲對智能指針的引用會更好 - 調用者函數是否已經使用智能指針?

至於「常量」的含義......你的意思是這樣

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

? 如果是的話,這將會適得其反,您可以向編譯器傳達「汽車」不會改變的事實(但大概您希望它改變!)。

或者你的意思是使函數 「常量」,像

class DAL{ 
    bool loadCar(int id, Car& car) const; 
} 

在後一種情況下,您與編譯器/ API用戶交流,方法「loadCar」不會修改DAL對象。如果這是真的,那麼這樣做不失爲一個好主意 - 不僅它能夠實現一些編譯器優化,而且在「合同」(函數簽名)中指定該函數不會修改DAL通常是一件好事,尤其是如果你在你的代碼中做了這個隱含的假設(這樣你就可以確保這一點是真實的,並且在將來沒有人會以改變「DAL」對象的方式修改「loadCar」函數)

+0

我只是想知道它是否更好 - 現在我真的不知道哪一個更好。 – ng5000 2009-10-09 10:26:59

+0

再次,與const我不知道。假設我們在DAL中沒有任何計數/緩存等,將函數設爲const可能是正確的。 – ng5000 2009-10-09 10:28:31

+1

從邏輯常量(從用戶的角度來看)和真正的常量(從dev的角度來看)之間的區別,我建議使用邏輯one>,只要用戶沒有看到任何修改,聲明const方法。特別是,緩存應該被聲明爲可變的。 – 2009-10-09 12:16:59