Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

creating objects dynamically in C++

I was just reading this thread and it occurred to me that there is one seemingly-valid use of that pattern the OP is asking about. I know I've used it before to implement dynamic creation of objects. As far as I know, there is no better solution in C++, but I was wondering if any gurus out there know of a better way. Generally, I run into this situation when I need to create one of several subclasses of an object based one something unknown at compile time (such as based on a config file). I use the object polymorphically once it is created.

There's another related situation when you're using a message-passing scheme (usually over TCP/IP) where each message is an object. I like to implement that pattern as letting each message serialize itself into some serialization stream interface, which works well and is fairly clean on the sending end, but on the receiver, I always find myself examining a header on the message to determine the type, then constructing an appropriate message object using the pattern from the linked article, then having it deserialize itself from the stream. Sometimes I implement it so that the construction and deserialization happen at the same time as part of the constructor, which seems more RAII, but that's small consolation for the mess of if/else statements figuring out the type.

Any better solutions out there? If you're going to suggest a 3rd party library, it should be free (and ideally open source) and I'd appreciate it if you could explain how the library accomplishes this feat.

like image 548
rmeador Avatar asked Apr 08 '26 05:04

rmeador


2 Answers

I think what you are asking is how to keep the object creation code with the objects themselves.

This is usually what I do. It assumes that there is some key that gives you a type (int tag, string, etc). I make a class that has a map of key to factory functions, and a registration function that takes a key and factory function and adds it to the map. There is also a create function that takes a key, looks it up in the map, calls the factory function, and returns the created object. As an example, take a int key, and a stream that contains the rest of the info to build the objects. I haven't tested, or even compiled, this code, but it should give you an idea.

class Factory
{
    public:
    typedef Object*(*Func)(istream& is);
    static void register(int key, Func f) {m[key] = f;}
    Object* create(key, istream& is) {return m[key](is);}
    private:
    std::map<key, func> m;
}

Then in each class derived from subobject, the register() method is called with the appropriate key and factory method.

To create the object, you just need something like this:

while(cin)
{
    int key;
    is >> key;
    Object* obj = Factory::Create(key, is);
    // do something with objects
}
like image 145
KeithB Avatar answered Apr 10 '26 18:04

KeithB


What you're describing here is termed the factory pattern. A variant is the builder pattern.

like image 44
Mr Fooz Avatar answered Apr 10 '26 19:04

Mr Fooz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!