0

次のように、C++ で Decorator パターンを実装しました。

#include <iostream>
#include <string>
#include <deque>
using namespace std;

// Abstract Component
template <class T>
class IArray 
{
public:
   virtual void insert(const T&) = 0;
   virtual ~IArray(){}

};

// Concrete Component
template <class T>
class Array : public IArray<T>
{
public:
   virtual void insert(const T& elem)
   {
      m_array.push_back(elem);
   }

private:
   deque<T>   m_array;
};

// Decorator 1
template <class T>
class PositiveArray : public IArray<T>
{
public:
   PositiveArray(IArray<T>* component):m_component(component)
   {

   }

   virtual void insert(const T& elem)
   {
      if (elem > 0)
      {
         m_component->insert(elem);
      }
      else
      {
         cerr << "You can't insert non-positive number." <<endl;
      }
   }
private:
   IArray<T>*   m_component;
};


// Decorator 2
template <class T>
class PrintArray : public IArray<T>
{
public:
   PrintArray(IArray<T>* component):m_component(component)
   {

   }

   virtual void insert(const T& elem)
   { 
      m_component->insert(elem);
      cout << "Element " << elem << " was inserted into the array." <<endl;
   }
private:
   IArray<T>*   m_component;
};

// Client
int main()
{
   typedef int MyType;

   PositiveArray<MyType> arr(new PrintArray<MyType>(new Array<MyType>));
   arr.insert(10);
   arr.insert(-10);

   int i;
   cin>>i;
   return 0;
}

printArray今、私はすべての配列機能を持ちたいと思っています。IArray で純粋仮想関数として記述し、その関数の次の実装を IArray の各子にコピーする必要がありますか?

   void printArray()
   {
      for (int i = 0; i < m_array.size(); ++i)
      {
         cout << "elem " <<i << " is " << m_array[i] <<endl;
      }
   }

コピーを回避できる解決策はありますか?

4

1 に答える 1

0

for_each_elementどちらかで実装しArray、 でインターフェイスを公開しますIArraystd::function< void(T const&) >andを取る 2 つのオーバーロードがありstd::function< void(T) >ます (2 つ目はオプションです)。今PrintArrayは1行のラムダ関数です。

boost::functionC++03 では、を使用できますが、これPrintArrayは書くのが面倒です。したがって、ここではあまり魅力的ではありません。

const_iterator別のアプローチとして、基になるデータに s を公開します。

余談ですが、dequeパフォーマンスは驚くほど貧弱です。まだ、あなたのコードには、std::vector. メモリの連続性が保証されている場合は、 を作成して、から直接インターフェイスを公開するconst_iteratorこともできます(実装は で)。 C++11 では2 行になり、 C++11 がなくても2 行になり、インラインまたはフリー関数として実装されます。T const*IArrayArrayfor_each_elementPrintArrayfor_each_elementIArray

ああ、私はPrintArrayメンバー関数ではなく無料関数を作成します。 for_each_elementメンバー関数である必要があるかもしれませんが、PrintArrayイテレータやfor_each_element.

于 2013-03-18T17:35:44.023 に答える