C ++中的OO设计-用未知类型的子代装饰父对象 [英] OO design in C++ - Decorating a parent object with unknown types of child

查看:53
本文介绍了C ++中的OO设计-用未知类型的子代装饰父对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在研究一个系统,其中的对象沿贝塞尔曲线进行动画处理。在用户定义的曲线上的各个点上,可能会发生动画对象必须做出反应的事件。

I'm currently working on a system within which objects animate along a bezier curve. At various, user defined, points on the curve, there can be an event which the animating object has to react to. This could be a change of speed, change on animation routine, change of facing direction etc...

到目前为止,我有以下AnimationEvent类。

So far I have the following AnimationEvent class.

class AnimationEvent
{
private:
    unsigned int    m_eventID;

    float   m_InteroplationPoint;

    float   m_SpeedInMPS;

public:
    AnimationEvent(unsigned int id, float interpolationPoint);
    ~AnimationEvent(void);

    const unsigned int getEventID();
    void setInterpolationPoint(float interpPoint);
    const float getInterpPoint();

    const float getSpeed();
};

每个事件均沿曲线分配为对象,并且在到达其插值点时会指定曲线类调用 getSpeed()函数以更改当前动画速度。

Each event is assigned as an object along a curve and when its interpolation point is reached, the curve class calls the getSpeed() function in order to change the current animation speed.

我真正想做的是来实现诸如Decorator设计模式之类的系统,在该系统中,事件可以用多个对象进行装饰,并且到达事件时,将应用所有装饰。我遇到的问题是我无法将指向父对象的指针传递给子对象,因为这将创建一个循环依赖项,但是还有一个问题,我不知道(在编译时)什么类型的动作

What I really want to do is to implement a system such as with the Decorator design pattern, where the event can be decorated with multiple objects and when reached, all decorations will be applied. The problem I am having is that I can't pass a pointer to the parent object to the child as this will then create a circular dependency, but I also have the problem where I don't know (at compilation) what type of actions the event will be decorated with.

任何有关如何克服这一点的想法将不胜感激!如果我忘记了可能有帮助的任何信息,我将尝试对其进行编辑。

Any ideas about how to overcome this would be greatly appreciated! If I've forgotten any info which might help, I'll try and edit it in.

推荐答案

您可以应用装饰器此问题的类似模式,如果您愿意跟踪对象先前发生的所有事件。您需要做的就是将每个事件存储在某种向量中。然后,您可以进行任何所需的操作。

You can apply a decorator-like pattern to this problem, if you are willing to keep track of all the events that have occurred to an object previously. All you need to do is store each event in a vector of some sort. Then you can do any sort of manipulations that you'd like.

#include <iostream>
#include <vector>
using namespace std;

class Animatee;
class AnimateEvent
{
public:
    virtual Animatee & perform(Animatee & on) = 0;
};

class Animatee
{
public:
    Animatee() : value(0){};

    void addEvent(AnimateEvent * event)
    {
        if(event != NULL)
        {
            events.push_back(event);
        }

    }

    Animatee & act()
    {
        for(vector<AnimateEvent * >::iterator it = events.begin(); it != events.end();++it)
        {
            AnimateEvent * event = *it;
            event->perform(*this);
        }

        return *this;
    }

    double value;   //don't do this, but something more encap'ed
private:

    vector<AnimateEvent * > events;
};

class Add : public AnimateEvent
{
    virtual Animatee & perform(Animatee & on)
    {
        on.value = on.value + 1;
        return on;
    }
};

class Subtract : public AnimateEvent
{
    virtual Animatee & perform(Animatee & on)
    {
        on.value = on.value - 1;
        return on;
    }
};

class Multiply : public AnimateEvent
{
    virtual Animatee & perform(Animatee & on)
    {
        on.value = on.value * 2;
        return on;
    }
};

class Div : public AnimateEvent
{
    virtual Animatee & perform(Animatee & on)
    {
        on.value = on.value / 2.0;
        return on;
    }
};

int main() {
    Animatee matee;
    matee.addEvent(new Add());

    //cout << "Before: " << matee.value << " After: " << matee.act().value << endl; <~~~ Undefined btw, acting on the object twice in one "statement"
    double before = matee.value;
    cout << "Before: " << before << " After: " << matee.act().value << endl;

    matee.addEvent(new Subtract());
    before = matee.value;
    cout << "Before: " << before << " After: " << matee.act().value << endl;

    matee.addEvent(new Subtract());
    before = matee.value;
    cout << "Before: " << before << " After: " << matee.act().value << endl;

    matee.addEvent(new Add());
    matee.addEvent(new Add());
    matee.addEvent(new Add());
    before = matee.value;
    cout << "Before: " << before << " After: " << matee.act().value << endl;

    matee.addEvent(new Multiply());
    before = matee.value;
    cout << "Before: " << before << " After: " << matee.act().value << endl;

    before = matee.value;
    cout << "Before: " << before << " After: " << matee.act().value << endl;

    return 0;
}

这篇关于C ++中的OO设计-用未知类型的子代装饰父对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆