您好我试图实施"装饰"真实例子上的模式,但我不能在客户端(主函数)中装饰我的对象(Burger * b)。当我输入"新奶酪"在ConcretteBurger()中 - Visual Studio向我显示了一个错误:"没有为类#34生成默认构造函数;干酪""
#include<iostream>
using namespace std;
class Burger{
public:
virtual int get_cost() = 0;
};
class ConcretteBurger: public Burger{
public:
int get_cost(){
return 3;
}
};
class BurgerDecorator:public Burger{
private:
Burger *b;
public:
BurgerDecorator(Burger* bb){
bb = b;
}
~BurgerDecorator(){
delete b;
}
int get_cost(){
return b->get_cost();
}
};
class Tomato:public BurgerDecorator{
public:
Tomato(Burger *b):BurgerDecorator(b){
}
int get_cost(){
return BurgerDecorator::get_cost() + 4;
}
};
class Cheese:public BurgerDecorator{
public:
Cheese(Burger *b):BurgerDecorator(b){}
int get_cost(){
return BurgerDecorator::get_cost()+3;
}
};
int main(){
Burger* b = new ConcretteBurger(new Cheese);
cout<<b->get_cost();
system("pause");
}
在声明功能之后,我没有理解概念:BurgerDecorator(b)的第二个问题。例如:
Tomato(Burger *b):BurgerDecorator(b){}
我在C ++书籍中找不到它。
谢谢
答案 0 :(得分:1)
在main
函数中,您应该这样做:
Burger* b = new Cheese(new ConcretteBurger);
而不是:
Burger* b = new ConcretteBurger(new Cheese);
奶酪装饰汉堡,而不是相反。更一般地说,decorator类接受对装饰类的引用,而不是相反的。
另请注意BurgerDecorator
的构造函数有错误。它应该是:
BurgerDecorator(Burger* bb){
b = bb;
}
甚至更好:
BurgerDecorator(Burger* bb): b{bb} {}
而不是您示例中的bb = b;
。
最后,在基类中添加一个虚拟析构函数以避免泄漏:
class Burger{
public:
virtual ~Burger() = default;
virtual int get_cost() = 0;
};
在wandbox上修复后再查看您的代码。
答案 1 :(得分:1)
您的代码中存在两个问题。 首先在BurgerDecorator中初始化:
BurgerDecorator(Burger* bb){
b = bb;
}
其次,ConcreteBurger的构造函数只有标准的构造函数。所以你可以在没有参数的情况下实例化汉堡:
Burger* b = new ConcretteBurger();
并将此汉堡传递给装饰器,因为装饰器有一个构造函数,其参数列表为Burgers(换句话说:国际象棋装饰汉堡):
Burger* decorator = new Cheese(b);
cout << decorator ->get_cost() << endl;
至少你对**的理解:BurgerDecorator(b)**:
这将调用基类的构造函数并传递参数。它被称为初始化列表。 Here您可以阅读更多相关信息。