带有数组的c++装饰器模式实现

C++ Decorator Pattern implementation with Arrays

本文关键字:模式 实现 c++ 数组      更新时间:2023-10-16

我在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;
      }
   }

有什么办法可以避免复制吗?

我将在Array中实现for_each_element,并在IArray中公开接口。它有2个超载,采取std::function< void(T const&) >std::function< void(T) >(第二个是可选的)。现在PrintArray是一个单行lambda函数。

在c++ 03中,你可以使用boost::function,而PrintArray写起来比较麻烦。所以这里就没那么诱人了。

作为另一种方法,将const_iterator s暴露给底层数据。

说句题外话,deque的性能出奇的差。到目前为止,你的代码中没有任何东西会让我认为你不能使用std::vector。如果您保证内存的连续性,您甚至可以将const_iterator设置为T const*,并直接从IArray公开接口(在Array中实现)。for_each_element在c++ 11中变成了两行代码,而PrintArray即使没有c++ 11或for_each_element也是两行代码,并且要么在IArray中内联实现,要么作为一个自由函数。

哦,我想让PrintArray成为一个自由函数而不是成员函数。for_each_element可能需要是一个成员函数,但是一旦你公开了迭代器和/或for_each_element,你应该能够在不访问私有数据的情况下访问PrintArray