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\$
12
  • 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, 2015 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\$ Aug 25, 2015 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\$ Aug 25, 2015 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\$ Aug 25, 2015 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\$ Aug 26, 2015 at 14:12

0

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.