2017-02-05 11 views
1

こんにちは、実際の例で「Decorator」パターンを実装しようとしましたが、(Burger * b)(main関数内)にオブジェクトをデコレートできません。私はConcretteBurger(で「新しいチーズ」と入力した場合) - Visual Studioがエラーを私に示しています。私はコンセプトを理解していなかった実際の例のデコレータパターン

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

「チーズ 『を』なしdefaulsコンストラクタクラスのために存在する」第二の問題:BurgerDecorator(b)関数宣言後。例:

Tomato(Burger *b):BurgerDecorator(b){} 

私はC++の本で見つけられませんでした。

Burger* b = new Cheese(new ConcretteBurger); 

の代わりにこの:バーガーではなく、反対を飾る

Burger* b = new ConcretteBurger(new Cheese); 

チーズ

は、あなたがこれを行う必要がありmain機能で

+0

「Cheese」のコンストラクタはCheese(Burger * b)のみです。したがって、あなたは 'Burger * 'で構築することしかできず、引数なしで作ることはできません。 'Burger *'を与えずに構築するには、引数を取らないコンストラクタ( 'Cheese()')を与えたり、コンストラクタに何も供給されていないときに使うデフォルトの引数を与えたりする「Cheese(Burger * b =新しいバーガー)」)。 –

答えて

1

ありがとうございます。一般的に、デコレータクラスは装飾されたクラスを参照し、その逆を参照しません。

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に固定された参照してください。

+0

ありがとうございます))今すぐ動作します! –

+0

@ SuleymanSuleyman-zadeようこそ。彼らがあなたの問題を解決したら、これを受け入れるか、他の答えの1つを自由に受け入れてください。これは将来の読者が探している情報を簡単に見つけるのに役立ちます。 – skypjack

1

コードには2つの問題があります。 BurgerDecoratorで 第1の初期化:ConcreteBurgerの

BurgerDecorator(Burger* bb){ 
    b = bb; 
} 

第二に、コンストラクタは、標準のコンストラクタを持っています。だから、引数なしでちょうどバーガーインスタンス化することができます

Burger* b = new ConcretteBurger(); 

をし、デコレータが(つまり:チェスはハンバーガーを飾る):バーガーのは、ArgumentListとコンストラクタを持っているので、デコレータにこのバーガーを渡す

Burger* decorator = new Cheese(b); 
cout << decorator ->get_cost() << endl; 

**の少なくともあなたの理解:BurgerDecorator(B)**:

これは、基底クラスのコンストラクタを呼び出すと、引数を渡します。 というイニシャライザのリストには、が含まれています。 Hereあなたはそれについてもっと読むことができます。

+0

ありがとうございます。今すぐ動作します:)あなたはTomato(Burger * b):BurgerDecorator(b){}とCheese(Burger * b):BurgerDecorator(b){}のコードの一部を説明してください。 –

+0

私はそれをしました。どういたしまして! – Soeren

関連する問題