装饰模式:将装饰功能单独放在一个类的方法中,并在该方法中调用父类的同名方法,从而达到增添功能的目的。
以下用两种方式实现装饰模式,但是都出现了中间环节被“跳过”的情况: +after correcting
#include <iostream>
using namespace std;
class PhoneCall
{
public:
PhoneCall();
virtual void call();
};
class AddPhoneCall :public PhoneCall
{
public:
AddPhoneCall(PhoneCall& pc);
virtual void call();
private:
PhoneCall _pc;
};
class MusicPhoneCall :public PhoneCall
{
public:
MusicPhoneCall(PhoneCall& pc);
virtual void call();
private:
PhoneCall _pc;
};
int main()
{
PhoneCall p = PhoneCall();
MusicPhoneCall m = MusicPhoneCall(p);
AddPhoneCall a = AddPhoneCall(m);
m.call();//after correcting
a.call();
return 0;
}
PhoneCall::PhoneCall() { cout << "PhoneCall constructor\n"; }
void PhoneCall::call()
{
cout << "calling...\n";
}
AddPhoneCall::AddPhoneCall(PhoneCall& pc) :_pc(pc) { cout << "AddPhoneCall constructor\n"; }
void AddPhoneCall::call()
{
cout << "addvertising...\n";
_pc.call();
}
MusicPhoneCall::MusicPhoneCall(PhoneCall& pc) :_pc(pc) { cout << "MusicPhoneCall constructor\n"; }
void MusicPhoneCall::call()
{
cout << "music...\n";
_pc.call();
}
输出:
PhoneCall constructor
PhoneCall constructor
MusicPhoneCall constructor
PhoneCall constructor
AddPhoneCall constructor
addvertising...
calling...
#include<iostream>
using namespace std;
class Component
{
public:
virtual void operation()
{
cout << "Component\n";
}
};
class Decorator: public Component
{
protected:
Component component;
public:
void setComponent(Component component)
{
this->component = component;
}
virtual void operation()
{
component.operation();
}
};
class ConcreteDecoratorA: public Decorator
{
public:
virtual void operation()
{
Decorator::operation();
cout << "ConcreteDecoratorA\n";
}
};
class ConcreteDecoratorB : public Decorator
{
public:
virtual void operation()
{
Decorator::operation();
cout << "ConcreteDecoratorB\n";
}
};
int main()
{
Component c;
ConcreteDecoratorA a;
ConcreteDecoratorB b;
a.setComponent(c);
b.setComponent(a);
a.operation();//after correcting
b.operation();
return 0;
}
输出:
Component
ConcreteDecoratorB
解答:
这两种实现方式的问题是一样的。结合构造函数的调用情况,我想会不会是因为参数类型的问题导致ConcreteDecoratorA的构造函数没有被调用,所以中间环节被“跳过”了。后来在CSDN问答里提问,得到的回答和我的猜测差不多,但更详细,以下为该用户的回答(感谢!):
b.setComponent(a);的时候的方法是类Decorator里的
参数是Component,而a的类型是ConcreteDecoratorA,被退化为Decorator,再退化为Component
所以自始至终都没有使用过ConcreteDecoratorA:类里的任何东西,自然不会输出ConcreteDecoratorA——豆丷