Ross Driedger
Source CodeClass Factory
This example extends last example from the Virtual Functions page.
Creating Objects
Many times we will know exactly what kind of objects we will create and we explicitly declare them in our code:
AK47 ak; ak.use();
Given that the lifetime of an object often outlives the scope in which it is declared, objects are managed through pointers to objects created on the free store:
AK47* p = new AK47; p -> use();
Using polymopism, implemented as virtual functions in C++, we can use a pointer to the base class.
Weapon* p = new AK47; p -> use();
In this example, we still know what kind of Weapon we will create. But is that realistic? Very often we will have situations where we don't know exactly what kind of object to create until the user is playing the game. Obviously we cannot anticipate what the user will do.
Factories are a set of Constructional Design Patterns -- patterns in software that have come into common use by developers because they solve reoccuring coding problems. In a factory, the developer constructs a special object or function that can create objects of a specific type at run time.
In this example, we have a function that takes an integer that represents the user's choice in Weapon. The function then constructs a concrete object of that type and returns it.
Weapon* weaponsFactory(int type) { switch(type) { case 2: return new AK47; case 3: return new BFG9000; case 4: return new BowieKnife; case 5: return new ICBM; case 6: return new M777_Howitzer; case 7: return new PointyStick; case 8: return new Taser; default: return 0; } }
A couple of things to note:
- Each of the objects creatable in the factory are derived from Weapon.
- The return is a pointer to that base class.
These two conditions must be met in C++ and other strongly typed languages.
vector<Weapon*> arsenal; //get the user's choice and pass that value to the factory: Weapon* p = weaponsFactory(choice); if(p) { arsenal.push_back(p); }
The code listing included allows the user to create any number of objects that have been derived from Weapon. A sample run is listed here:
C:\factory>war 0 - Quit 1 - Fire Weapons 2 - Create New AK47 3 - Create new BFG9000 4 - Create new Bowie Knife 5 - Create new ICBM 6 - Create new M777 Howizter 7 - Create new Pointy Stick 8 - Create new Taser 2 0 - Quit 1 - Fire Weapons 2 - Create New AK47 3 - Create new BFG9000 4 - Create new Bowie Knife 5 - Create new ICBM 6 - Create new M777 Howizter 7 - Create new Pointy Stick 8 - Create new Taser 3 0 - Quit 1 - Fire Weapons 2 - Create New AK47 3 - Create new BFG9000 4 - Create new Bowie Knife 5 - Create new ICBM 6 - Create new M777 Howizter 7 - Create new Pointy Stick 8 - Create new Taser 4 0 - Quit 1 - Fire Weapons 2 - Create New AK47 3 - Create new BFG9000 4 - Create new Bowie Knife 5 - Create new ICBM 6 - Create new M777 Howizter 7 - Create new Pointy Stick 8 - Create new Taser 5 0 - Quit 1 - Fire Weapons 2 - Create New AK47 3 - Create new BFG9000 4 - Create new Bowie Knife 5 - Create new ICBM 6 - Create new M777 Howizter 7 - Create new Pointy Stick 8 - Create new Taser 6 0 - Quit 1 - Fire Weapons 2 - Create New AK47 3 - Create new BFG9000 4 - Create new Bowie Knife 5 - Create new ICBM 6 - Create new M777 Howizter 7 - Create new Pointy Stick 8 - Create new Taser 7 0 - Quit 1 - Fire Weapons 2 - Create New AK47 3 - Create new BFG9000 4 - Create new Bowie Knife 5 - Create new ICBM 6 - Create new M777 Howizter 7 - Create new Pointy Stick 8 - Create new Taser 8 0 - Quit 1 - Fire Weapons 2 - Create New AK47 3 - Create new BFG9000 4 - Create new Bowie Knife 5 - Create new ICBM 6 - Create new M777 Howizter 7 - Create new Pointy Stick 8 - Create new Taser 6 0 - Quit 1 - Fire Weapons 2 - Create New AK47 3 - Create new BFG9000 4 - Create new Bowie Knife 5 - Create new ICBM 6 - Create new M777 Howizter 7 - Create new Pointy Stick 8 - Create new Taser 7 0 - Quit 1 - Fire Weapons 2 - Create New AK47 3 - Create new BFG9000 4 - Create new Bowie Knife 5 - Create new ICBM 6 - Create new M777 Howizter 7 - Create new Pointy Stick 8 - Create new Taser 8 0 - Quit 1 - Fire Weapons 2 - Create New AK47 3 - Create new BFG9000 4 - Create new Bowie Knife 5 - Create new ICBM 6 - Create new M777 Howizter 7 - Create new Pointy Stick 8 - Create new Taser 1 AK47::use() executed. RangeWeapon::use() executed. Weapon::use() executed. BFG9000::use() executed. ChargeWeapon::use() executed. Weapon::use() executed. BowieKnife::use() executed. MeleeWeapon::use() executed. Weapon::use() executed. ICBM::use() executed. BallisticWeapon::use() executed. Weapon::use() executed. M777_Howitzer::use() executed. RangeWeapon::use() executed. Weapon::use() executed. PointyStick::use() executed. MeleeWeapon::use() executed. Weapon::use() executed. Taser::use() executed. ChargeWeapon::use() executed. Weapon::use() executed. M777_Howitzer::use() executed. RangeWeapon::use() executed. Weapon::use() executed. PointyStick::use() executed. MeleeWeapon::use() executed. Weapon::use() executed. Taser::use() executed. ChargeWeapon::use() executed. Weapon::use() executed. 0 - Quit 1 - Fire Weapons 2 - Create New AK47 3 - Create new BFG9000 4 - Create new Bowie Knife 5 - Create new ICBM 6 - Create new M777 Howizter 7 - Create new Pointy Stick 8 - Create new Taser 0 BowieKnife dtor executed. RangeWeapon dtor executed. Weapon dtor executed. BFG9000 dtor executed. ChargeWeapon dtor executed. Weapon dtor executed. BowieKnife dtor executed. MeleeWeapon dtor executed. Weapon dtor executed. ICBM dtor executed. BallisticWeapon dtor executed. Weapon dtor executed. M777_Howitzer dtor executed. RangeWeapon dtor executed. Weapon dtor executed. PointyStick dtor executed. MeleeWeapon dtor executed. Weapon dtor executed. Taser dtor executed. ChargeWeapon dtor executed. Weapon dtor executed. M777_Howitzer dtor executed. RangeWeapon dtor executed. Weapon dtor executed. PointyStick dtor executed. MeleeWeapon dtor executed. Weapon dtor executed. Taser dtor executed. ChargeWeapon dtor executed. Weapon dtor executed.