Examples
Example: Using a factory function to insert a post-constructor call. Consider:
class B { // hierarchy root
protected:
B() {/* ... */ }
virtual void PostInitialize() {/* ... */ } // called right after construction
public:
template<class T>
static shared_ptr<T> Create() { // interface for creating objects
shared_ptr<T> p( new T );
p->PostInitialize();
return p;
}
};
class D : public B {/* ... */ }; // some derived class
shared_ptr<D> p = D::Create<D>(); // creating a D object
This rather fragile design sports the following tradeoffs:
Derived classes such as D must not expose a public constructor. Otherwise, D's users could create D objects that don't invoke PostInitialize. Allocation is limited to operator new.B can, however, override new (see Items 45 and 46). D must define a constructor with the same parameters that B selected. Defining several overloads of Create can assuage this problem, however; and the overloads can even be templated on the argument types. If the requirements above are met, the design guarantees that PostInitialize has been called for any fully constructed B-derived object. PostInitialize doesn't need to be virtual; it can, however, invoke virtual functions freely.
|