3
\$\begingroup\$

I'm designing a Factory in C++ with raw pointers, but I'd like to use smart pointers when possible as is recommended with the Factory pattern in newer C++. Unfortunately my compiler is a bit old (gcc 4.4.6) and not all of the features of C++11 (let alone C++0x) are available to me.

I cannot use nullptr, which is the most troubling aspect to me. I'd love a standard review and any tips for adding smart pointers to my code.

#ifndef SERVICE_FACTORY_H_
#define SERVICE_FACTORY_H_

#include <string>
#include <map>
#include <memory>

class Service {
  public:  
    virtual void free() = 0;
};

typedef Service* (*CreationFunction)(void);

class Counter : public Service {
  public:
    static Service* create() { return new Counter(); }
    void free() { delete this; }
};

class ServiceFactory {
  public:
    ~ServiceFactory() {
      _registeredServices.clear();
    }

    static ServiceFactory* getInstance() {
      static ServiceFactory instance;
      return &instance;
    }

    void registerService(const std::string &serviceName, CreationFunction fn) {
      _registeredServices[serviceName] = fn;
    }

    Service* createService(const std::string &serviceName) {
      auto it = _registeredServices.find(serviceName);
      if(it != _registeredServices.end())
        return it->second();
      return NULL;
    }
  private:
    ServiceFactory() {
      registerService("COUNTER", &Counter::create);
    }

    ServiceFactory(const ServiceFactory&) { /* Nothing implemented yet */ }

    ServiceFactory& operator=(const ServiceFactory&) { return *this; }

    std::map<std::string, CreationFunction> _registeredServices;
};

#endif // SERVICE_FACTORY_H_

EDIT

Here's a driver:

#include "ServiceFactory.h"
#include <iostream>

int main() {
  Service* counter = ServiceFactory::getInstance()->createService("COUNTER");
  if(counter) {
    std::cout << "Counter was made." << std::endl;
    counter->free();
  } else {
    std::cout << "Counter was not made." << std::endl;
  }

  return 0;
}

Here's the compilation process succeeding on ideone (with C++14).

\$\endgroup\$
  • 7
    \$\begingroup\$ Next time, please wait for the question to be reopened instead of posting it again. The previous one had already received reopen votes. \$\endgroup\$ – Jamal Aug 25 '15 at 16:20
  • 2
    \$\begingroup\$ You can always use boost it has all the smart pointers that are in the standard (its where they came from after all). \$\endgroup\$ – Martin York Aug 25 '15 at 18:07
  • 1
    \$\begingroup\$ Also you don't need to return smart pointers. You could return references. Let the factory retain ownership of the objects (but that depends a bit on the usage model). \$\endgroup\$ – Martin York Aug 25 '15 at 18:07
  • 2
    \$\begingroup\$ @erip: Yep. I would not want the user responsible for deleting any of them. But that does not necessarily means shared pointers. If resources can be shared then reference may be an alternative. But it really depends on the usage pattern. \$\endgroup\$ – Martin York Aug 25 '15 at 22:39
  • 1
    \$\begingroup\$ Voting to close as the code generates 12 errors when you try and compile it. Obviously untested and sample code. \$\endgroup\$ – Martin York Aug 26 '15 at 14:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.