C++ (Qt)class ImageData : public QSharedData // хранит сами данные (приватный класс){ ...}; class Image // хранит указатель на данные (публичный класс){public: ...private: QSharedDataPointer<ImageData> d;};
C++ (Qt){ Image i; // Создался объект Image, внутри создался объект Image Data // Владеет данными объект i}// Вышли из области видимости, объект i разрушился, он использовал данными один - данные разрушились.
C++ (Qt){ Image i; { Image i2; i2.load( ... ); i = i2; // i и i2 указывают на одни и те-же данные, но объекта два } // Объект i2 разрушился, но данные остались, т.к. i на них ссылается.}
C++ (Qt)// Вышли из области видимости, объект i разрушился, он использовал данными один - данные разрушились.
C++ (Qt)class ImageManager{public: Image load( const QString &name ); private: QMap<QString, Image> m_cache;};
C++ (Qt)#include <boost/shared_ptr.hpp>#include <boost/weak_ptr.hpp>#include <string>#include <map>#include <iostream> class Resource{public: Resource() {} Resource( const std::string &name ) : m_data( name ) {} std::string m_data;}; typedef boost::shared_ptr<Resource> ResourcePtr; class ResourceManager{public: ResourcePtr load( const std::string &name ); void clearCache(); void dumpCache() const; private: typedef boost::weak_ptr<Resource> SResourcePtr; typedef std::map<std::string, SResourcePtr> MapCache; MapCache m_cache;}; ResourcePtr ResourceManager::load( const std::string &name ){ MapCache::iterator it = m_cache.find( name ); if( it != m_cache.end() ) { ResourcePtr o = it->second.lock(); if( o ) return o; else m_cache.erase( it ); } ResourcePtr r( new Resource( name ) ); m_cache[ name ] = SResourcePtr( r ); return r;} void ResourceManager::clearCache(){ MapCache::iterator it; for( it = m_cache.begin(); it != m_cache.end(); ++it ) { if( !it->second.lock() ) m_cache.erase( it ); }} void ResourceManager::dumpCache() const{ std::cout << "Cache num: " << m_cache.size() << std::endl; MapCache::const_iterator it; for( it = m_cache.begin(); it != m_cache.end(); ++it ) { ResourcePtr o = it->second.lock(); std::cout << "key: " << it->first << " -> " << ( ( o )? o->m_data : "unload" ) << std::endl; }} int main( int argc, char **argv ){ ResourceManager man; { ResourcePtr o1 = man.load( "AAA" ); ResourcePtr o2 = man.load( "BBB" ); ResourcePtr o3 = man.load( "BBB" ); std::cout << o1->m_data << " " << o2->m_data << " " << o3->m_data << " " << std::endl; } ResourcePtr o4 = man.load( "DDD" ); man.dumpCache(); man.clearCache(); man.dumpCache(); return 0;}