使用flyweight模式在位图对象之间共享位图

时间:2009-09-30 09:06:15

标签: c++ boost design-patterns

Hello堆栈溢出程序,我有一个设计使用flyweight模式来共享位图对象之间共享的位图,这些位图对象管理绘图操作等,并集成在gui库中。这是一个嵌入式设备,因此内存非常宝贵。目前,我已经完成了一个工作实现,其中包含一个计数使用情况的light类的auto_ptr的std :: vector。我知道这是一个坏主意,可能会泄漏,所以我正在重写这一部分。我正在考虑使用boost :: shared_ptr。我的问题的关键是,如果没有使用,我希望被释放的位图。如果我有一个shared_ptr池,我最终加载了一次使用的位图。我正在考虑使用shared_ptr :: use_count()来删除位图,如果use_count()== 1.但是文档警告生成代码use_count()。基本上问题是飞重模式与个别重物的释放。你认为有更好的方法吗?

2 个答案:

答案 0 :(得分:7)

您可以使用增强弱指针池,以便池不计入所有权。

只有位图对象有提升共享指针,这样他们决定何时释放位图。

弱指针池允许我们检索已经构造的位图:

创建位图对象时,您可以:

  • 从弱指针获取共享指针(如果它不为空),

  • 或以其他方式加载新的位图,从中创建一个新的共享指针,并插入/替换池中的弱指针。

以下是使用池地图的示例代码:

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <map>
#include <string>
#include <iostream>

// represents the bitmap data
class Bitmap
{
public :
    Bitmap( std::string const& name ) : name( name )
    {
        std::cout << "Bitmap " << name << std::endl ;
    }

    ~Bitmap()
    {
        std::cout << "~Bitmap " << name << std::endl ;
    }

    std::string name ;
};

// the flyweight pool
class Factory
{
public :

    typedef std::map< std::string , boost::weak_ptr< Bitmap > > Map ;

    boost::shared_ptr< Bitmap > get( std::string const& what )
    {
        Map::iterator x = map.find( what );

        // retrieve existing object from map's weak pointers

        if( x != map.end() )
        {
            if( boost::shared_ptr< Bitmap > shared = x->second.lock() )
            {
                return shared ;
            }
        }

        // populate or update the map

        boost::shared_ptr< Bitmap > shared( new Bitmap( what ) );
        boost::weak_ptr< Bitmap > weak( shared );
        map.insert( std::make_pair( what , weak ) );
        return shared ;
    }

private :
    Map map ;
};


int main(int argc, char** argv)
{
    Factory f ;

    // we try our flyweight bitmap factory ...

    boost::shared_ptr< Bitmap > a = f.get( "a" );
    boost::shared_ptr< Bitmap > b = f.get( "b" );

    // a is not made again
    boost::shared_ptr< Bitmap > a2 = f.get( "a" );

    a.reset();
    a2.reset();

    // a is destroyed before ------

    std::cout << "------" << std::endl ;
}

答案 1 :(得分:0)

shared_ptr的想法是它为您管理对象的生命周期。您不必检查使用计数。每个用户有一个shared_ptr,删除用户时删除shared_ptrs,当没有剩下的用户时,它会删除你的位图。如果你有一个特殊的例程,你需要调用它来删除位图而不能只在析构函数中这样做,你可以在创建时将特殊的删除函数传递给shared_ptr。