Реализация шаблона C ++ Decorator с массивами

Я реализовал шаблон Decorator в 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;
}
}

Есть ли какое-либо решение, которое можно избежать копирования?

0

Решение

Я бы реализовал for_each_element в любом Arrayи выставить интерфейс в IArray, Он имеет 2 перегрузки, которые принимают std::function< void(T const&) > а также std::function< void(T) > (второй не обязателен). Сейчас PrintArray является одной строкой лямбда-функции.

В C ++ 03 вы можете использовать boost::function, а также PrintArray больше раздражает писать. Так что здесь это менее заманчиво.

Как другой подход, разоблачить const_iteratorс базовыми данными.

Как в сторону, deque производительность на удивление плохая. Пока что в вашем коде нет ничего, что заставило бы меня думать, что вы не можете использовать std::vector, Если бы вы гарантировали непрерывность памяти, вы могли бы даже иметь const_iteratorдолжно быть 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,

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector