I l@ve RuBoard |
![]() ![]() |
1.10 Customizing Structure with Policy ClassesOne of the limitations of templates, mentioned in Section 1.4, is that you cannot use templates to customize the structure of a class—only its behavior. Policy-based designs, however, do support structural customization in a natural manner. Suppose that you want to support nonpointer representations for SmartPtr. For example, on certain platforms some pointers might be represented by a handle—an integral value that you pass to a system function to obtain the actual pointer. To solve this you might "indirect" the pointer access through a policy, say, a Structure policy. The Structure policy abstracts the pointer storage. Consequently, Structure should expose types called PointerType (the type of the pointed-to object) and ReferenceType (the type to which the pointer refers) and functions such as GetPointer and SetPointer. The fact that the pointer type is not hardcoded to T* has important advantages. For example, you can use SmartPtr with nonstandard pointer types (such as near and far pointers on segmented architectures), or you can easily implement clever solutions such as before and after functions (Stroustrup 2000a). The possibilities are extremely interesting. The default storage of a smart pointer is a plain-vanilla pointer adorned with the Structure policy interface, as shown in the following code. template <class T> class DefaultSmartPtrStorage { public: typedef T* PointerType; typedef T& ReferenceType; protected: PointerType GetPointer() { return ptr_; } void SetPointer(PointerType ptr) { pointee_ = ptr; } private: PointerType ptr_; }; The actual storage used is completely hidden behind Structure's interface. Now SmartPtr can use a Storage policy instead of aggregating a T*. template < class T, template <class> class CheckingPolicy, template <class> class ThreadingModel, template <class> class Storage = DefaultSmartPtrStorage > class SmartPtr; Of course, SmartPtr must either derive from Storage<T> or aggregate a Storage<T> object in order to embed the needed structure. ![]() |
I l@ve RuBoard |
![]() ![]() |