0

我在 C++ 中实现了装饰器模式,如下所示:

#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,并在IArray. 它有 2 个需要std::function< void(T const&) >和的重载std::function< void(T) >(第二个是可选的)。现在PrintArray是一个单行 lambda 函数。

在 C++03 中你可以使用boost::function,PrintArray写起来更烦人。所以在这里它不那么诱人。

作为另一种方法,将const_iterators 暴露给基础数据。

顺便说一句,deque性能出奇的差。到目前为止,您的代码中没有任何内容让我认为您不能使用std::vector. 如果您保证内存连续性,您甚至可以让您const_iterator的 s 成为T const*并直接从IArray(使用 中的实现Array)公开接口。 for_each_element在 C++11 中变成了两行,PrintArray即使没有 C++11 或者for_each_element是 2 行,并且要么内联实现,IArray要么作为自由函数实现。

哦,我会做PrintArray一个自由函数而不是成员函数。 for_each_element可能需要成为成员函数,但是PrintArray一旦公开迭代器和/或for_each_element.

于 2013-03-18T17:35:44.023 回答