[ fromfile: factory.xml id: factorybenefits ]
One of the benefits of factory patterns is that we can manage the created objects in a pool (reusing the ones that can be reused).
Indirect object creation also makes it possible to decide at runtime which class objects to create.
This enables the "plugging in" of replacement classes without requiring changes in the client code.
Section 16.2 shows an example of a
method that makes use of factory objects to create trees of connected, client-defined objects based on the
contents of an XML file.
In src/libs/metadata/abstractmetadataloader.h
, there is another example of a
factory method that manages singleton instances of MetaDataLoader
in such a way that it becomes easy to write programs that can switch between derived metadata loaders
without code breakage.
Another benefit of the Factory method (or indirect object creation in general) is that they can enforce post-constructor initialization of objects, including the invocation of virtual functions.
An object is not considered "fully constructed" until the constructor has finished executing.
An object's vpointer does not point to the correct
vtable until the end of the constructor's execution.
Therefore, calls to methods of this
from the constructor cannot use
polymorphism!
Factory methods are required when any polymorphic behavior is needed during object initialization. Example 16.8 demonstrates this problem.
Example 16.8. src/ctorpoly/ctorpoly.cpp
#include <iostream> using namespace std; class A { public: A() { cout << "in A ctor" << endl; foo(); } virtual void foo() { cout << "A's foo()" << endl; } }; class B: public A { public: B() { cout << "in B ctor" << endl; } void foo() { cout << "B's foo()" << endl; } }; class C: public B { public: C() { cout << "in C ctor" << endl; } void foo() { cout << "C's foo()" << endl; } }; int main() { C* cptr = new C; cout << "After construction is complete:" << endl; cptr->foo(); return 0; }
Its output is given in Example 16.9.
Example 16.9. src/ctorpoly/ctorpoly-output.txt
src/ctorpoly> ./a.out in A ctor A's foo() in B ctor in C ctor After construction is complete: C's foo() src/ctorpoly>
Notice that the wrong version of foo()
was called when the new C
object was constructed.
Section 22.1
discusses vtables in more detail.
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |