Boost logo

Boost :

From: Anthony Liguori (anthony_at_[hidden])
Date: 2003-09-07 16:42:53


Hi Rob,

As some others have mentioned, I think there have been a number of
factory submissions. I myself submitted a proof-of-concept a while back
(available at http://rockhopper.homelinux.org/factories). That of
course evolved into something a bit different--virtual constructors.

The idea is a mem_fn-like wrapper for constructors to created function
objects automatically for constructors. Then a simple std::map can be
used to create a "factory" like so:

std::map<std::string, boost::function<Base *(int)> > factory;

factory["one"] = boost::ctor_fn<Sub *(int)>();

The nice thing is that since we're dealing with function objects, all
signature constructor can be used and boost::bind can also be used to
default subclass arguments and such.

At the time, it was suggested that ctor_fn be expanded to support
overloaded new operators (like the placement new operator). As these
things go, things piled up and I never implemented that. If there's
general interest in taking this forward and wants to help take this
forward, I'd be willing to open it up again.

Best Regards,
Anthony Liguori

Rob & Lori wrote:

> For those of you who are unfamiliar with pluggable factories, I
> suggest reading the following C++ Report article:
> http://www.adtmag.com/joop/crarticle.asp?ID=1520
>
> To give a brief description, pluggable factories allow programmers to
> create instances of a class by just referencing a class identifier.
> Pluggable factories are extremely helpful anytime you wish to
> construct a class based on outside input such as reconstructing
> classes sent over a TCP/IP stream, constructing classes read from a
> file, constructing classes to execute commands read in from a
> scripting/macro language, etc.
>
> The pluggable factory has these features:
> 1. Classes can be registered and unregistered dynamically
> 2. Any data type that implements the assignment and comparison
> operators can be used as a class identifier type
> 3. Classes can be registered with multiple class identifier's, even if
> they are of different data types
> 3. Instances of new classes can be created simply by passing the
> correct class identifier
> 4. The class identifier value can be retrieved for any given
> registered class
>
> Let me know what you guys think.
>
> Rob Geiman
>
>
> Example usage:
>
> typedef ObjectFactory<Command> CommandFactory;
>
> static std::string open_file_command = "open_file";
> static std::string close_file_command = "close_file";
> static std::string find_text_command = "find_text";
>
> ...
>
> CommandFactory::Register<OpenFileCommand>(open_file_command);
> CommandFactory::Register<CloseFileCommand>(close_file_command);
> CommandFactory::Register<FindTextCommand>(find_text_command);
>
> ...
>
> // Loop through macro stream, reading in and executing all commands
> std::string cmd_text;
>
> while (macro_stream.good() && !macro_stream.eof())
> {
> macro_stream >> cmd_text;
>
> Command *cmd = CommandFactory::Create(cmd_text);
>
> if (cmd)
> {
> cmd->ExtractParams(macro_stream);
> cmd->Execute();
> }
> else
> {
> std::cout << "Unknown command: " << cmd_text << std::endl;
> }
> }
>
> ...
>
> std::cout << "Class OpenFileCommand registered with id " <<
> CommandFactory::GetClassId<OpenFileCommand, string>() << std::endl;
> std::cout << "Class CloseFileCommand registered with id " <<
> CommandFactory::GetClassId<OpenFileCommand, string>() << std::endl;
> std::cout << "Class FindTextCommand registered with id " <<
> CommandFactory::GetClassId<OpenFileCommand, string>() << std::endl;
>
> ...
>
> CommandFactory::Unregister(open_file_command);
> CommandFactory::Unregister(close_file_command);
> CommandFactory::Unregister(find_text_command);
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk