【发布时间】:2017-09-01 19:08:33
【问题描述】:
我正在尝试学习装饰器设计,并且我想出了一些很棒的东西,但我不知道我的想法是否可以编译。所以我创建了一些类:
这是基类
class parameter
{
public:
parameter(){}
parameter(double mini, double maxi, double def) :
mini(mini),
maxi(maxi),
def(def)
{}
double mini, maxi, def;
double val;
virtual double getValue() { return val; }
virtual void setValue(double v) { val = v; }
};
这个类存储smoothedParameters。 smoothedParameter 将在需要平滑时将自己添加到 SmootherManager 中,并在完成后将其删除。
class SmootherManager
{
public:
SmootherManager() {}
juce::Array<smoothedParameter *> CurSmoothingList;
void add(smoothedParameter * sp)
{
CurSmoothingList.addIfNotAlreadyThere(sp);
}
void remove(smoothedParameter * sp)
{
CurSmoothingList.removeFirstMatchingValue(sp);
}
void doSmoothing()
{
for (auto & sp : CurSmoothingList)
sp->incValue();
}
};
这个类随着时间的推移取值并输出一个平滑的值。
class smoothedParameter : public parameter
{
public:
//smoothedParameter(){}
smoothedParameter(double smoothingSpeed, SmootherManager & manager, parameter * p) :
smoothingSpeed(smoothingSpeed),
manager(manager),
p(p)
{}
double smoothingSpeed;
SmootherManager & manager;
parameter * p;
rosic::ExponentialSmoother smoother;
double getValue()
{
return smoother.getCurrentValue();
}
void setValue(double v)
{
p->setValue(v);
smoother.setTargetValue(p->getValue());
if (!smoother.finishedSmoothing())
manager.add(this);
}
void incValue()
{
smoother.getSample();
if (smoother.finishedSmoothing())
manager.remove(this);
}
};
这个类接受一个值并通过修饰符列表随着时间的推移对其进行修改。
class modulatedParameter : public parameter
{
public:
modulatedParameter(parameter * p) : p(p) {}
juce::Array<modifier *> modulationInputs;
parameter * p;
double getValue()
{
double totalMod = 0;
for (const auto & m : modulationInputs)
totalMod += m->val;
return totalMod * p->getValue();
}
void setValue(double v)
{
p->setValue(v);
}
void add(modifier * sp)
{
modulationInputs.addIfNotAlreadyThere(sp);
}
void remove(modifier * sp)
{
modulationInputs.removeFirstMatchingValue(sp);
}
};
这就是它的工作原理。你有一个平滑器和一个调制器。如果您在调制器内部构建一个平滑器,您将得到一个平滑调制器。如果在平滑器内部构建调制器,则会得到非平滑调制器。
这是我想使用这些类的方式:
// create the smoother manager
SmootherManager smManager;
// create modulatable parameter
auto mp = new modulatedParameter(new parameter(0.0, 1.0, 0.0));
// create a smoothable parameter
auto sp = new smoothedParameter(0.01, smManager, new parameter(0.0, 1.0, 0.0));
// create a modulatable parameter where its modifiers are smoothed
auto mp_sp = new modulatedParameter(new smoothedParameter(0.01, smManager, new parameter(0.0, 1.0, 0.0)));
// create a parameter where values are smoothed, but the modulation is not
auto sp_mp = new smoothedParameter(0.01, smManager, modulatedParameter(new parameter(0.0, 1.0, 0.0)));
好的!问题来了。
modifier myMod;
// add a modifier to sp_mp, can't do it, sp_mp has no add function.
sp_mp->add(&myMod);
我正在尝试将调制器添加到平滑参数的调制参数中。我想了一个办法,但这似乎不对。
auto mp = new modulatedParameter(sp_mp->p);
mp->add(&myMod)
sp_mp = new smoothedParameter(0.01, smManager, mp));
任何时候我想添加/删除修饰符,我都必须经过几个步骤。我可以想办法解决这个问题,但我对什么是实用方法感到迷茫,因为我不知道 C++ 的所有可能性。装饰器设计的重点是对象可以具有不同的功能集。 ......似乎我需要为每个类都有一个“添加/删除”功能,这违背了这个设计的目的。
【问题讨论】:
标签: c++ class decorator hierarchy