8 horas en 115 líneas de código en C++

Vino Chuy. Ayer nos juntamos. Eso siempre significa peda. Me levanté muy crudo. Maldita última cerveza Frayle del Sierra Madre. Esa fue la que me puso pedo.

Antier en la noche quise plasmar en código mi idea para los catálogos de SiCaPoP y me di cuenta de mi nula experiencia con plantillas (template). Sólo pude obtener quejas del compilador sobre mi sintaxis. Por lo que hoy me senté a escribir una pequeña prueba de concepto. Tardé todo el día obtener algo en limpio y aquí está para que se diviertan entendiéndolo.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-

#include
#include
#include

/// Interface
template<class DTO, class DAO>
class ICatalog
{
  public:
    virtual void Load () = 0;
    virtual void Unload () = 0;
    virtual void Reload () = 0;
    virtual void setDAO (DAO& dao) = 0;
    virtual DTO& operator[] (std::string key) = 0;
    typedef typename std::map<std::string, DTO>::iterator iterator;
    virtual iterator begin () = 0;
    virtual iterator end () = 0;
};

/// Class which implement the interface
// This class is a template and a map decorator :)
template<class DTO, class DAO>
class Catalog : public ICatalog<DTO, DAO>
{
  public:
    Catalog ();
    virtual void Load ();
    virtual void Unload ();
    virtual void Reload ();
    virtual void setDAO (DAO& dao);

    // This is very cool
    typedef typename ICatalog<DTO, DAO>::iterator iterator;
    virtual DTO& operator[] (std::string key);
    virtual iterator begin () { return catalog.begin (); }
    virtual iterator end () { return catalog.end (); }
    virtual ~Catalog ();

  private:
    std::map<std::string, DTO> catalog;
    DAO dao;
};

template<class DTO, class DAO>
Catalog<DTO, DAO>::Catalog ()
{
  std::cout << "Constructor" << std::endl;
}

template<class DTO, class DAO>
void Catalog<DTO, DAO>::Load ()
{
  std::cout << "Load" << std::endl;
  catalog["m1"] = 1;
  catalog["m2"] = 2;
}

template<class DTO, class DAO>
void Catalog<DTO, DAO>::Unload ()
{
  std::cout << "Unload" << std::endl;
}

template<class DTO, class DAO>
void Catalog<DTO, DAO>::Reload ()
{
  std::cout << "Reload" << std::endl;
}

template<class DTO, class DAO>
void Catalog<DTO, DAO>::setDAO (DAO& \_dao)
{
  dao = \_dao;
  std::cout << "setDAO = " << dao << std::endl;
}

template<class DTO, class DAO>
DTO& Catalog<DTO, DAO>::operator[] (std::string key)
{
  return catalog[key];
}

template<class DTO, class DAO>
Catalog<DTO, DAO>::~Catalog ()
{
  std::cout << "Destructor" << std::endl;
}

// Simplifying the declarations
typedef Catalog<int, std::string> IntegerCatalog;

/// Factory of objects
class CatalogFactory
{
  private:
    IntegerCatalog intcat;

  public:
    IntegerCatalog& getInteger () { return intcat; }
};

// Always there is a main
int main (int argc, char \*\*argv)
{
  CatalogFactory factory;
  std::string dao = "testing string";

  factory.getInteger ().setDAO (dao);
  factory.getInteger ().Load ();

  for (IntegerCatalog::iterator iter = factory.getInteger ().begin ();
      iter != factory.getInteger ().end ();
      iter++) {
    std::string key = (\*iter).first;
    int value = (\*iter).second;
    std::cout << key << " = " << value << std::endl;
  }

  return 0;
}