I want a template to return different classes

94 views Asked by At

long time reader,

I was wondering if anyone could help me make my code a bit simpler by using a template to return different classes derived from the same base. So I can call the functions on the classes instead of rewriting the function for each object call in a manager class. Here an example of one my current function calls:

void setLoopImage(AnimationManagerIndex & managerIndex, bool b)
{
    switch (managerIndex.animationClass)
    {
        case ANIMATION_CLASS_BASE:
        {
            vAnimationObjectBase[managerIndex.index].setLoopImage(b);
            break;
        }
        case ANIMATION_CLASS_MOVING:
        {
            vAnimationObjectMoving[managerIndex.index].setLoopImage(b);
            break;
        }
        case ANIMATION_CLASS_MOVING_BEZIER:
        {
            vAnimationObjectMovingBezier[managerIndex.index].setLoopImage(b);
            break;
        }
    }
}

I want to create a template function that returns these classes like so:

template<class T>
T & getAnimationObject(AnimationManagerIndex & managerIndex)
{
    switch (managerIndex.animationClass)
    {
        case ANIMATION_CLASS_BASE:
        {
            return vAnimationObjectBase[managerIndex.index];
        }
        case ANIMATION_CLASS_MOVING:
        {
            return vAnimationObjectMoving[managerIndex.index];
        }
        case ANIMATION_CLASS_MOVING_BEZIER:
        {
            return vAnimationObjectMovingBezier[managerIndex.index];
        }
    }
}

So the first function will become:

void setLoopImage(AnimationManagerIndex & managerIndex, bool b)
{
    getAnimationObject(managerIndex).setLoopImage(b);
}
2

There are 2 answers

4
VuVirt On

You don't need templates for this. You can achieve this by making a base (abstract) class that has defines a (pure) virtual setLoopImage function.

class Base
{
    virtual setLoopImage(bool b) = 0;
}; 

Derive each of the following classes from the one above: vAnimationObjectBase, vAnimationObjectMoving and vAnimationObjectMovingBezier.

Then your getAnimationObject function would return Base&:

Base& getAnimationObject(AnimationManagerIndex & managerIndex)
{
    switch (managerIndex.animationClass)
    {
        case ANIMATION_CLASS_BASE:
        {
            return vAnimationObjectBase[managerIndex.index];
        }
        case ANIMATION_CLASS_MOVING:
        {
            return vAnimationObjectMoving[managerIndex.index];
        }
        case ANIMATION_CLASS_MOVING_BEZIER:
        {
            return vAnimationObjectMovingBezier[managerIndex.index];
        }
    }
}

Every derived class will implement the pure virtual setLoopImage function and you will call it on the derived class.

0
Xirema On

The usual solution to this problem is classical inheritance:

struct drawable_interface {
    virtual void setLoopImage(bool) = 0;
};

drawable_interface & getAnimationObject(AnimationManagerIndex & managerIndex) {
    /*Same code as before*/
}