C ++ и STL: конструкторская фабрика - PullRequest
1 голос
/ 24 августа 2011

У меня большая фабрика, и я пытаюсь понять, как она выглядит красиво.
Существует около 40 возможных комбинаций объект / конструктор:

if(algorithm == "SHA-1")
    return new HashImpl<...>(algorithm, seed, size);
if(algorithm == "SHA-224")
    return new HashImpl<...>(algorithm, seed, size);
if(algorithm == "SHA-256")
    return new HashImpl<...>(algorithm, seed, size);
... 
if(algorithm == "AES" || algorithm == "AES128")
    return new BlockCipherImpl<...>(algorithm, seed, size);  
...
if(algorithm == "HmacSHA1")
    return new HmacImpl<...>(algorithm, seed, size);
...

Есть ли способ поместить это в карту, чтобы я, по крайней мере, мог покончить с последовательным поиском? У меня проблемы с выяснением, как сделать конструктор функтором.

РЕДАКТИРОВАТЬ: код можно найти здесь:
http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/src/crypto/SecureRandomImpl.cpp, начиная с линии 130.

Ответы [ 3 ]

5 голосов
/ 24 августа 2011

Не нужно использовать их причудливые новомодные карты.

template <class Impl>
BaseImplementation* makeAlgo (const std::string& algo, 
                                const byte* seed, size_t size)
{
    return new Impl(algo, seed, size);
}

typedef BaseImplementation* makeAlgo_t (const std::string& algo, 
                                          const byte* seed, size_t size);

typedef struct { std::string name; makeAlgo_t func; } NamedAlgoMaker_t;


NamedAlgoMaker_t factory[] = {
  { "SHA-1",     makeAlgo< HashImpl <...> >  },
  ...
  { "HmacSHA1",  makeAlgo< HmacImpl <...> > },
  ...
};

Если вы сохраняете массив отсортированным, вы можете использовать двоичный поиск, чтобы быстро найти алгоритм.

Конечно, из этих вещей вы также можете построить карту (или хэш / неупорядоченную карту), если хотите.

1 голос
/ 24 августа 2011

Вы можете использовать либо карту лямбда-функций, возможно,

0 голосов
/ 24 августа 2011

Так что все равно будет визуально некрасиво.Но вы можете сделать это быстрее следующим образом:

  1. Создайте ~ 40 фабричных методов, каждый из которых возвращает один из этих вариантов.
  2. Создайте карту, где fnPointerTypedef является типом возвратавашего фабричного метода.
  3. Просмотрите словарь и верните результат любой функции, которую вы ищете.
  4. Создайте перечисление, которое дает номер для каждой опции (например, SHA-1 = 0, SHA-224 = 1 и т. Д.).
  5. Создайте карту, отображающую имя строки в {int | enum}.
  6. Создайте массив указателей на функции, и каждая точка в массиве будет указывать на соответствующий соответствующий фабричный метод.
  7. Поиск словаря и возвращение functionArray [enumInt];

(Edit: спасибо nm за более прямую реализацию)

...