2009-07-21 6 views
1

Ich habe ein Objekt-Cache-Klasse wie folgt aus:Constructor der Klasse in Vorlage

#include "boost/thread/mutex.hpp" 
#include "boost/unordered_map.hpp" 

template <typename type1, typename type2> 
class objectCache 
{ 
public: 
    objectCache() 
    { 
     IDCounter = 0; 
    } 
    ~objectCache() 
    { 
     for (it=free_objects.begin() ; it != free_objects.end(); it++) 
      delete (*it).second; 
     for (it=busy_objects.begin() ; it != busy_objects.end(); it++) 
      delete (*it).second; 
    } 
    type1* objectCache::Get() 
    { 
     boost::mutex::scoped_lock(io_mutex); 
     if(free_objects.size() > 0) 
     { 
      it = free_objects.begin(); 
      type1 *temp = (*it).second; 
      busy_objects[(*it).first] = temp; 
      free_objects.erase(free_objects.begin()); 
      return temp; 
     } 
     type1 * temp = new type2; 
     ++IDCounter; 
     busy_objects[IDCounter] = temp; 
     return temp; 
    } 
    void objectCache::Pushback(type1) 
    { 
     boost::mutex::scoped_lock(io_mutex); 
     free_objects[ID] = socket; 
     it = busy_objects.find(ID); 
     busy_objects.erase(it); 
    } 
protected: 
private: 
    boost::mutex io_mutex; 
    long long IDCounter; 
    boost::unordered_map<long long, type1*> free_objects; 
    boost::unordered_map<long long, type1*> busy_objects; 
    typename boost::unordered_map<long long, type1*>::iterator it; 
}; 

class A{ 
public: 
    A(int num){ 
     number = num; 
    } 
    int number; 
}; 
int main(int argc, char* argv[]) 
{ 
    objectCache<a, a(1)> intcache; 
    A* temp = intcache.Get(); 
    cout <<temp->number <<endl; 
    system("pause"); 
    return 0; 
} 

ich gewusst, dass „Typname Typ2“ war unnötig, aber ich brauche eine Möglichkeit, eine Klasse-Objekt, das einen Konstruktor mit Parameter müssen übergeben wie Klasse A für die Vorlage. oder war das eine andere Möglichkeit, dies zu tun? bitte hilfe.

+0

Können Sie in Worten erklären, was Sie mit Ihrer Klasse Objectcache zu erreichen versuchen? Auf diese Weise müssen die Leser diese Informationen nicht aus Ihrem Code "disassemblieren". und Sie könnten bessere Antworten erhalten, weil Ihre Frage spezifischer ist. – Tobias

Antwort

0

vielmehr einen expliziten Wert als vorbei, in einem Objekt übergeben, die für Sie Ihre Instanz erstellt:

template <typename type1> 
struct DefaultInstanceCreator { 
    type1 * operator()() const { 
    return new type1; 
    } 
}; 

template < typename type1 
     , typename InstanceCreator = DefaultInstanceCreator<type1> > 
class objectCache { 
public: 
    objectCache (InstanceCreator const & instCreator) 
    : instCreator_ (instCreator) { 
    } 
    type1* Get() { 
    type1 * temp = instCreator_(); 
    } 
private: 
    InstanceCreator instCreator_; 
}; 

Dann können Sie Ihr Objekt haben es eigene spezifische Schöpfer ist:

class A { 
public: 
    A(int num){ 
     number = num; 
    } 
    int number; 

public: 
    struct CreateInstance { 
    CreateInstance (int value) 
     : value_ (value) { 
    } 
    A * operator()() const { 
     return new A(value_); 
    } 
    int value_; 
    }; 
}; 

int main(int argc, char* argv[]) { 
    objectCache<A, A::CreateInstance> intcache (A::CreateInstance (1)); 
    A* temp = intcache.Get(); 
    return 0; 
} 

Die Vorteil dieses Ansatzes ist, dass Sie Ihren Cache mit Objekten verwenden können, deren Konstruktoren eine andere Anzahl von Argumenten haben.

+0

danke, Ihre Lösung in der Tat, was ich brauche, andere Lösung funktioniert aber nur in bestimmten Klassen, muss dieser Ansatz CreateInstance in jeder Objektklasse erstellen, die im Cache gespeichert werden müssen, aber immer noch besser als eine neue Vorlage für jede Klasse im Cache zwischengespeichert schreiben. –

0

Sie können die Template-Parameter auf der Methode haben:

template <typename type2> 
type1* objectCache::Get() 
0

Sie so etwas wie dies wollen Sie?

template <typename type1> 
class objectCache 
{ 

// ... 

template<typename type2> 
type1* Get(type2 value) 
{ 
    boost::mutex::scoped_lock(io_mutex); 
    if(free_objects.size() > 0) 
    { 
     it = free_objects.begin(); 
     type1 *temp = (*it).second; 
     busy_objects[(*it).first] = temp; 
     free_objects.erase(free_objects.begin()); 
     return temp; 
    } 
    type1 * temp = new type1(value); 
    ++IDCounter; 
    busy_objects[IDCounter] = temp; 
    return temp; 
} 

// ... 

}; 

int main(int argc, char* argv[]) 
{ 
    objectCache<A> intcache; 
    A* temp = intcache.Get(1); 
    cout << temp->number << endl; 
    system("pause"); 
    return 0; 
} 
0
int main(int argc, char* argv[]) 
{  
    objectCache<a, a(1)> intcache; 
    ... 
} 

ist falsch. Sie sollen die Typen angeben, die von der Klasse objectCache verwendet werden. Es sollte so etwas wie

objectCache<A, A> intcache; 

In der Klasse Objectcache sein, wenn Sie Objekte von A instanziiert, werden Sie zu haben einen Parameter an den Konstruktor übergeben.

Zum Beispiel:

... 
type1 * temp = new type1(1); 
...