2010-11-14 51 views
0

我有一個包含對象指針向量的類。我在該類中有一個GetObject(..)函數,它查看矢量,找到所需的對象,並返回指向它的指針。但是,如果該類的用戶在該返回的指針上執行了delete(),則我的程序將崩潰,因爲該向量仍然有一個指向該對象的指針,現在是無效對象。所以,在我的GetObject()類中,我可以返回一個const指針,但這並不能解決問題,因爲您仍然可以刪除該對象。該對象是可變的,所以我不能返回一個指向const對象的指針。我想我可以通過返回對象的引用來防止刪除,但我有我的函數返回NULL,如果有錯誤。我想我可以傳回通過參數的對象引用,然後返回和錯誤值這樣如何在不使用const的情況下防止刪除指針?

//-1 on object on found. 0 for success. Object is passed back in 
// the function parameter result. 
int MyObject::GetObject(int object_id, Item& result) 

這是對這種情況最好的解決辦法?

回答

6

解決此問題的最佳方法是使用共享所有者智能指針,如shared_ptr,您可以在Boost,C++ TR1和C++ 0x中找到它。

智能指針是一個容器,它爲您管理動態分配對象的生命週期。當您完成使用時,它需要承擔對象的責任。

使用共享所有者智能指針,您可以擁有多個智能指針,這些智能指針共享動態分配的對象的所有權。保留一個引用計數,用於跟蹤有多少智能指針擁有該對象的所有權,並且當最後擁有的智能指針被銷燬時,動態分配的對象是delete d。

在C++中手動管理資源非常困難,而且編寫代碼看起來很正確,而且大部分時間都正常工作,但這仍然不正確。通過使用智能指針和其他擁有資源的容器(如標準庫容器),您不再需要手動管理資源。當您的所有資源管理都是自動執行時,編寫正確的代碼將變得非常容易。

C++中的自動資源管理是使用名爲Resource Acquisition is Initialization (RAII)的設計模式完成的,該模式可以說是您作爲C++程序員應該熟悉的最重要的設計模式。

+0

+1:這是一個很好的解決方案的最相關的原因是,使用智能指針,他們不能再直接調用對象上的刪除,沒有很多明顯的錯誤/明顯邪惡的黑客。正如詹姆斯已經描述的那樣,還有其他的好處,但這是最適用於這個問題的。 – 2010-11-14 22:40:19

0

如果您可以使用boost庫,則可以使用smart pointers來確保指針保持有效。實際上,每次對智能指針的引用都會將其「使用次數」增加1.當在引用上調用reset函數時,引用將消失,並且使用計數器遞減。只要某個對象仍然握住智能指針,引用就會有效。請注意,其他類將能夠更改其指向的內容,但無法刪除它。 (我的描述主要涉及智能指針 - 不同類型的指針會有所不同,但總體思路保持不變)。

1

您應該返回對該對象的引用。沒有找到對象時,有兩種方法可以處理這種情況。

首先,您可以使用Null Object Pattern以實現該情況下的特殊值。這可能對你的情況沒有意義。

另一種方式是將它分成兩個方法,一個可以用來檢查一個合適的元素是否存在,另一個是檢索它。

許多STL的容器或算法實現這兩種,或者通過返回一個過去最結束迭代,或通過具有empty() returns false作爲調用等frontback的方法的先決條件。

+0

另一種方法是在沒有找到對象的情況下拋出異常,我想。無論您的來電者是否會感謝您的這種看法,都取決於您返回null時他們目前正在做的事情。 – 2010-11-14 22:46:23

2

代碼中的任何人也可以嘗試去引用NULL。你會阻止他們這樣做嗎?如果你的容器擁有這個對象,並且你清楚地說明了這一點(返回一個原始指針通常很清晰或者在文檔中提及),那麼任何刪除它的人,結果都是他們自己的錯。您可以保證防止刪除對象的唯一方法是防止用戶獲得原生的引用或指針 - 在這種情況下,他們只是無法訪問該對象。

2

誰是你們班的客戶?如果他們不是你的致命的敵人,你可以問他們不要刪除對象。否則,總會有一種方法讓他們「攪亂」你。

好的,一種可能的解決方案是使析構函數爲私有。這將防止每個人刪除該對象。但是,對象必須以某種方式刪除自己(delete this),也許可以通過一些名爲DeletObjectButDontBlameMeIfAppCrashes的函數來刪除它。如果所有者是其他類,那麼可以將析構函數設置爲受保護類和所有者類作爲此類的朋友。

相關問題