you can put forward all the requirements for resource implementations as follows:
class t_resource_interface { protected: virtual ~t_resource_interface(); public: virtual t_serialization* serializeResource() = 0; virtual t_thing* cloneResource() = 0; }; typedef enum t_load_from_url { LoadFromURL = 0 } t_load_from_url; typedef enum t_load_from_memory { LoadFromMemory = 0 } t_load_from_memory; typedef enum t_copy_constructor { CopyConstructor = 0 } t_copy_constructor; template < typename TResourceImplementation > class t_resource : public t_resource_interface { public: t_resource(const t_copy_constructor& copyCtor, const t_resource& other) : t_resource_interface(), d_implementation(TResourceImplementation::CopyConstructor(other.d_implementation)) { MONUnusedParameter(copyCtor); } t_resource(const t_load_from_url& fromFile, const t_url& url) : t_resource_interface(), d_implementation(TResourceImplementation::LoadFromURL(url)) { MONUnusedParameter(fromFile); } t_resource(const t_load_from_memory& fromMemory, const t_serialization& serialization) : t_resource_interface(), d_implementation(TResourceImplementation::LoadFromMemory(serialization)) { MONUnusedParameter(fromMemory); } virtual ~t_resource() { } public: virtual t_serialization* serializeResource() { return this->d_implementation->serializeResource(); } virtual t_thing* cloneResource() { return this->d_implementation->cloneResource(); } private: t_auto_pointer<TResourceImplementation> d_implementation; private: t_resource(const t_resource&); t_resource& operator=(const t_resource&); }; class t_image_resource_implementation : public t_resource_interface { private: static t_image_resource_implementation* ValidationCheck(const t_image_resource_implementation* const arg) { assert(arg && "allocation or argument error"); if (0 == arg) { return 0; } else if (0 == arg->isValid()) { delete res; return 0; } else { return arg; } } public: static t_image_resource_implementation* CopyConstructor(const t_image_resource_implementation* const other) { return ValidationCheck(new t_image_resource_implementation(other, ...)); } static t_image_resource_implementation* LoadFromURL(const t_url& url) { return ValidationCheck(new t_image_at_url_resource_implementation(url, ...)); } static t_image_resource_implementation* LoadFromMemory(const t_serialization& serialization) { assert(serialization); if (0 == serialization) { return 0; } else { return ValidationCheck(new t_image_resource_implementation(serialization, ...)); } } public: virtual t_serialization* serializeResource() { return this->createSerialization(); } virtual t_thing* cloneResource() { return this->clone(); } }; typedef t_resource<t_image_resource_implementation> t_image_resource; t_error_code ConvertImageToGrayscale(const t_url& sourceUrl, const t_url& destinationUrl) { t_image_resource imageResource(LoadFromURL, sourceUrl); }
source share