簡體   English   中英

如何應對返回指針的生命周期?

[英]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_ptrbooststd ):

     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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM