Skip to content

Instantly share code, notes, and snippets.

@iwadon
Created October 31, 2012 13:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iwadon/3987091 to your computer and use it in GitHub Desktop.
Save iwadon/3987091 to your computer and use it in GitHub Desktop.
Factory関数を複数登録できるようにした(その2)
#ifndef BASE_HH_INCLUDED
#define BASE_HH_INCLUDED 1
struct Base
{
virtual const char *ClassName() const
{
return "Base";
}
};
#endif // !defined(BASE_HH_INCLUDED)
#ifndef BASE_FACTORY_REGISTRY_HH_INCLUDED
#define BASE_FACTORY_REGISTRY_HH_INCLUDED 1
#include <cstddef>
#include "base.hh"
#include <iostream>
class BaseFactoryRegistry
{
public:
BaseFactoryRegistry()
: count_(0)
{
}
void RegisterFactory(Base *(*factory)())
{
factories_[count_] = factory;
++count_;
}
Base *NewBase(size_t n)
{
return (factories_[n])();
}
size_t Count() const
{
return count_;
}
static BaseFactoryRegistry *Instance()
{
static BaseFactoryRegistry instance;
return &instance;
}
private:
Base *(*factories_[10])();
size_t count_;
};
#define BASE_FACTORY_REGISTRATION(klass) \
struct BaseFactoryRegistration_##klass { \
BaseFactoryRegistration_##klass() { \
BaseFactoryRegistry::Instance()->RegisterFactory(New##klass); \
} \
static Base *New##klass() { \
return new klass; \
} \
}; \
BaseFactoryRegistration_##klass base_factory_registration_##klass
#endif // !defined(BASE_FACTORY_REGISTRY_HH_INCLUDED)
#include "base.hh"
#include "base_factory_registry.hh"
struct Derived : public Base
{
const char *ClassName() const
{
return "Derived";
}
};
BASE_FACTORY_REGISTRATION(Derived);
#include "base.hh"
#include "base_factory_registry.hh"
struct Derived2 : public Base
{
const char *ClassName() const
{
return "Derived2";
}
};
BASE_FACTORY_REGISTRATION(Derived2);
#include "base.hh"
#include "base_factory_registry.hh"
struct Derived3 : public Base
{
const char *ClassName() const
{
return "Derived3";
}
};
BASE_FACTORY_REGISTRATION(Derived3);
#include "base_factory_registry.hh"
#include <iostream>
int main()
{
for (size_t i = 0; i < BaseFactoryRegistry::Instance()->Count(); ++i) {
Base *base = BaseFactoryRegistry::Instance()->NewBase(i);
std::cout << base->ClassName() << std::endl;
}
return 0;
}
CXX = g++
CXXFLAGS = -Wall -Wextra -O2 -g
CPPFLAGS =
AR = ar
LD = g++
LDFLAGS =
LIBS =
RM = rm -f
all: ok ng
clean:
$(RM) ok ng
$(RM) libderived.a
$(RM) main.o derived.o derived2.o derived3.o
ok: main.o derived.o derived2.o derived3.o
$(LD) $(LDFLAGS) -o $@ main.o derived.o derived2.o derived3.o
ng: main.o libderived.a
$(LD) $(LDFLAGS) -o $@ main.o -L. -lderived
main.o: main.cc base_factory_registry.hh
$(CXX) $(CXXFLAGS) -o $@ -c $<
derived.o: derived.cc base.hh base_factory_registry.hh
$(CXX) $(CXXFLAGS) -o $@ -c $<
derived2.o: derived2.cc base.hh base_factory_registry.hh
$(CXX) $(CXXFLAGS) -o $@ -c $<
derived3.o: derived3.cc base.hh base_factory_registry.hh
$(CXX) $(CXXFLAGS) -o $@ -c $<
libderived.a: derived.o derived2.o derived3.o
$(RM) $@; $(AR) crs $@ derived.o derived2.o derived3.o
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment