/* \file Test another less simple factory idiom. Factory can create several objects, which can be delivered on a first-in-first-out basis. The delivery takes place by transfering ownership. */ #include <list> #include "Deriveds.hh" #include "OwnedPtr.hh" using namespace MangoPtr; /* Simple factory class that can store many created objects. The objects are delivered in the order they were created (FIFO, first-in-first-out). The delivery method (getObj) returns an ownership instead of accepting a non-const Owned, as does FactoryFIFO in testIdiomFactoryFIFO1.cc. The owner that gives ownership must be alive when the other owner takes ownership. This requires a second list to be create, called 'delivered'. */ class FactoryFIFO { std::list<Owned<Base*, OShared> > owners; std::list<Owned<Base*, OShared> > delivered; public: void create(const std::string& type) { if (type=="derived1") { owners.push_back(); owners.back().takeOwnership(new Derived1); } else if (type=="derived2") { owners.push_back(); owners.back().takeOwnership(new Derived2); } else if (type=="derived3") { owners.push_back(); owners.back().takeOwnership(new Derived3); } else throw std::logic_error("Unknown type"); } Ownership<Base*, OShared> getObj() { Owned<Base*, OShared>& owner = owners.front(); if (owner.isNull()) throw std::logic_error("No object created"); // Must move away from front so getObj can always pick // up new object by calling front(). delivered.splice(delivered.begin(), owners, owners.begin()); return delivered.front().giveOwnership(); } }; /* Get \a num objects form \a factoryFIFO. */ void getObjects(FactoryFIFO& factoryFIFO, int num) { std::cout << "Getting FIFO objects" << std::endl; Owned<Base*, OShared> mango; for (int i=0; i<num; i++) { mango.takeOwnership( factoryFIFO.getObj() ); mango()->callVirtual(); } } int main() { try { std::cout << "Using FactoryFIFO again" << std::endl; FactoryFIFO factoryFIFO; // create five objects factoryFIFO.create("derived3"); factoryFIFO.create("derived2"); factoryFIFO.create("derived1"); factoryFIFO.create("derived2"); factoryFIFO.create("derived3"); // get only four objects getObjects(factoryFIFO, 4); std::cout << "Done FactoryFIFO use" << std::endl; } catch (const std::exception& e) { std::cout << e.what() << std::endl; } }