Creating class object dynamically in a 'manager' class

So let's see if I can explain this right.

I have an object manager class that handles a few derived classes. Everything to do with the derived classes is sorted out in this manager class so I only need to call handleObjects() from within my main and it sorts everything out. Each of the derived class has a 'creation condition' which is hard coded into the manager class. A function within the manager class takes an input which is compared to the creation condition to determine whether the derived class object is created.

So just to write things out here pseudo style...

Base;

Derived1;
Derived2;
...
Derivedn;

(will be adding more derived classes as my program developes.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class ObjectManager
{
    public:
        ObjectManager();

        void handleObjects();

    private:
        void createObject(int input);

        // hard_coded_creation_conditions
};

void ObjectManager::createObject(int input)
{
    // Cycle through all Derived classes creation conditions. k=1..n
    // If Derived_k creation condition == input
    // Create object of Derived_k using more hard coded data
}


So the above is what I'm looking to do but I'm not quite sure how to do it.

I will be storing the hard coded data (perhaps 3 data vals for each Derived class) in an array/vector data member of the Manager class. Now just how to dynamically create the Derived objects. I would like to have it as above in the form of a loop so there ideally would be an array storing perhaps pointers to the derived classes and if the creation condition is met I could do something like (I know it's wrong)...

1
2
3
4
5
6
7
8
9
vector<Base*> vector_of_pointers_to_derived_classes(?!?)

void ObjectManager::createObject(int input)
{
    if (Derived_k creation condition == input)
    {
        Base *p = new vector_of_pointers_to_derived_classes[k];
    }
}


Hopefully you can see what I'm looking to do. Difficult to google the right thing here. Templates pop up a lot when dealing with this sort of thing but I don't think that would work here.

So any ideas?
C++ is a statically typed language with no support for reflection. You will have to manually check for each value and manually create each instance. Copy and Paste is your friend, or, even better, compiler tools.
Hmm I had a feeling it might come down to having to go through each class individually... Would a factory type design approach be useful here, I know veeery little about factory design methods but I think it has something to do with creating objects.

Edit: Perhaps I could create one instance of each Derived type, then create a clone of it using references and what not. Maybe tho it would just be easier to type out extra code...
Last edited on
I think cycling through the options in your createObject method is the way to go. I think you could do something like

1
2
3
4
5
6
7
8
typedef Base * (*bfp)()
std::map<int, bfp> g_mapDerivedClasses;

// Init code somewhere
g_mapDerivedClasses.insert(1, funcToCreateDerived1);
g_mapDerivedClasses.insert(2, funcToCreateDerived2);
...
g_mapDerivedClasses.insert(k, funcToCreateDerivedk);


but I don't see much gain, though there is a lot of additional annoyance, nevermind the difficulty to follow and implement. Maybe post more code and someone can offer a better solution to the problem you're trying to solve?
Macros, people, macros!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Base {};
class MyClass1 : public Base {};
class MyClass2 : public Base {};
class MyClass3 : public Base {};
//...etc...
 
std::map<std::string, Base *(*)()> Factory;
#define MakeInstanceGetter(clazz) \
Base *Make_##clazz(){ return new clazz; } \
Base *(*ignore_##clazz##_clutter)() = Factory[#clazz] = &Make_##clazz
MakeInstanceGetter(MyClass1);
MakeInstanceGetter(MyClass2);
MakeInstanceGetter(MyClass3);
//...etc... 


You can then call each getter by its name:
Base *obj = Factory[TheNameOfTheClassAsAStandardString]();

Proof of Compilation: http://ideone.com/iM45O (yes, I know about the memory leaks ;) )

The "Base *(*ignore_##clazz##_clutter)() =" thing is to make a global variable to cheat the compiler into running the code that assigns to Factor[name]. otherwise, you will have issues with your compiler because you cannot run code outside of a function. Also, this has to be done this way for ease because you cannot make functions in functions. Just ignore these variables.
Last edited on
Topic archived. No new replies allowed.