[英]How to cope with lifetime of returned pointer?
我正在制作一組表示圖像的類。 此類的一個應用是在一組平鋪圖像上繪制圖片。 抽象圖像類如下所示:
class Image
{
public:
virtual Pixel* findPixel( Point p ) =0;
virtual bool isDrawable( Point p ) =0;
virtual bool contains( Point p ) =0;
};
我預見的問題是,如果我做這樣的課:
class TiledImage : public Image
{
std::vector<Image*> tiles;
public:
Pixel* findPixel( Point p )
{
// find the tile that contains the point.
// ask it for the pixel that contains the point.
// return the pixel.
}
// etc....
};
設計用於根據需要創建,保存和刪除非常大的圖像的小節(圖塊)的用戶,則用戶可能會存儲指向最終可能不再存在的Pixel對象的指針。
一種選擇是要求用戶在完成操作后重新簽入像素,例如:
Pixel* p = image.findPixel( aPoint );
// do stuff
image.returnPixel( p ); // p is not guaranteed to be valid after this point.
p->doSomething(); // this is not guaranteed to work.
我不是很喜歡這樣,因為如果用戶不返回像素,那么它可能真的會干擾平鋪圖像的操作-忘記返回像素可能會導致像素完全鎖定,因為它不會無法刪除不再需要的圖塊。 它們將被鎖定,以確保指向像素的指針保持有效。 鎖定的原因可能使用戶難以發現。
另外,這種關注是專門的。 在典型情況下,您不會期望像素消失,直到圖像消失。
有沒有更好的方法來處理這種情況? 智能指針? 完全不返回參考嗎? 首先,讓TiledImage從Image繼承沒有意義嗎? 當我希望圖形很大時,我當然希望能夠將TiledImage作為Image傳入。
謝謝。
兩種可能性(至少):
使用shared_ptr
( boost
或std
):
std::vector<shared_ptr<Image>> tiles; // No longer have to explicitly // delete the elements. shared_ptr<Pixel> findPixel( Point p ) { ... } shared_ptr<Pixel> p = image.findPixel( aPoint ); p->doSomething(); // Fine, as the internal pointer will not be // deleted due to use of the smart pointer.
返回Pixel
的副本。 僅當始終希望找到Pixel
或存在可以返回以指示不存在的默認值時,才可行。
次要點是,所有成員函數都暗示它們不會更改Image
因此請考慮使其成為const
。
RAII無疑是到達這里的方式。 您的Pixel類應該在其析構函數中調用image.returnPixel(this)
,而findPixel
應該返回shared_ptr<Pixel>
。 如果在完成用戶操作后不能刪除像素,則可以使用自定義刪除器返回shared_ptr,該自定義刪除器不會刪除Pixel,而是調用returnPixel
。
當向量被銷毀時,類似std::vector
這樣的事情的迭代器顯然是無效的,我不認為這與您的情況有何不同。
我的建議是通過引用返回像素,因為這清楚地表明它沒有移交所有權。 另外,提供有關無效行為的良好文檔。
已經為shared_ptr
提出了一些建議,如果您采用這種方法,由於所有權屬於映像,返回一個weak_ptr
而不是shared_ptr
似乎是一個不錯的決定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.