在具有所有權語義的公共API中傳遞原始指針應該很少,只有在絕對必要時才能完成。例如。與您的界面無法更改的代碼進行交互。
在私有API中傳遞原始指針,例如在一個班級的成員內部是沒有問題的。
考慮以下三個功能:
void f(A* a);
void g(std::unique_ptr<A> a);
void h(std::shared_ptr<A> a);
的f
所有權語義不明確。如果您是f
的客戶,則需要閱讀文檔以確定f
是否將取消分配a
,或忽略a
的所有權問題。
g
的所有權語義是明確的。當您致電g
時,您將a
的所有權轉讓給g
,您不再對此負責。 g
將取消分配a
或將該資源的所有權轉移到別處。
h
的所有權語義很清楚。當您撥打h
時,您和h
成爲a
的共同所有者。最後一個關閉燈。
void q(boost::intrusive_ptr<A> a);
q
具有相同的所有權語義h
。主要的區別是,必須存在以下免費功能:
intrusive_ptr_add_ref(A*);
intrusive_ptr_release(A*);
如果你是f
作者和你打電話a
這些功能,你應該記錄你這樣做。你的客戶不一定知道你是誰。如果您是f
的客戶,則無法知道f
是否會調用這些功能,除非您閱讀其文檔。
如果您是f
的作者,並且打算撥打intrusive_ptr_*
函數,則可以通過編寫代碼q
來明確地在您的界面中進行此操作。
但通常沒有強迫A
編寫intrusive_ptr_*
函數的作者的強制性理由。通過編寫h
,您可以獲得與q
相同的所有權語義,而不會對A
強加任何的進一步需求。
在內存開銷
如果您創建shared_ptr
有:
shared_ptr<A> p = make_shared(arguments-to-construct-an-A);
那麼你shared_ptr
將擁有完全相同的內存開銷爲intrusive_ptr
。該實現將在相同的內存分配中分配A和refcount。您的客戶不需要知道或關心您的shared_ptr
如此有效地構建。
其中一個注意事項:如果該對象在函數期間保證有效,那麼我寧願傳遞一個引用,這意味着沒有所有權問題。它更自我記錄。 – 2011-04-19 06:34:22