面向对象的设计在C ++ - 装饰与未知类型的子的父对象(OO design in C++ - D

2019-09-27 17:40发布

我目前的工作中哪些对象沿着贝塞尔曲线动画的系统上。 在所定义的各种用户,指出在曲线上,可以存在其中动画对象具有到反应的事件。 这可能是速度的变化,变化的动画例程,面临方向等的变化......

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

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()以改变当前的动画速度的功能。

我真正想要做的是实现一个系统,如与装饰设计模式,该事件可以与多个对象进行装饰,并达到时,所有的装饰将被应用。 我遇到的问题是,我不能一个指针传递给父对象的孩子,因为这会再创建一个循环依赖,但我也有这个问题,我不知道(在编译)什么类型的行动该事件将被装饰。

如何克服这种任何想法,将不胜感激! 如果我忘了任何信息,这可能会帮助,我会尝试和编辑。

Answer 1:

你可以申请一个装饰状的图案这个问题,如果你愿意让已经发生的对象,以前的所有事件的轨道。 所有你需要做的是每个事件存储在某种类型的载体。 然后,你可以做任何类型的,你想操作的。

#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;
}


Answer 2:

如上所述你只支持一次微速功能,这将惨不忍睹,除非一分不少。

有两个不同的问题。 第一个是一个可能的改变到内部动画参数(这是应该是不透明的可能定位引擎),第二个是在速度的变化(这是不不透明)。

我想解决两个正交。

着眼于速度,接下来的问题是要如何装饰相互组合。 难道他们加,乘,更换,形成对输出速度上限或下限?

什么地方的状态信息是他们允许访问?

假设它们被馈送沿曲线的位置,并且只有最后速度装饰意味着什么, std::function<double(double)>将做精作为速度装饰类型。

这是效率的顺序相同调用上virtual函数或两个。 并且注射器或装饰可以捕捉为所欲为的内部状态...



文章来源: OO design in C++ - Decorating a parent object with unknown types of child