2009-07-21 6 views
1

J'ai une classe de cache d'objets comme celui-ci:Constructeur de classe dans le modèle

#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; 
} 

Je connu que « typename type2 » était inutile mais je besoin d'un moyen de passer un objet de classe qui ont un constructeur avec un paramètre comme classe A au modèle. ou leur était une autre façon de le faire? aidez s'il vous plaît.

+0

Pouvez-vous expliquer avec des mots ce que vous essayez d'atteindre avec votre classe objectcache? De cette façon, les lecteurs n'auront pas à "désassembler" cette information de votre code; et vous pourriez obtenir de meilleures réponses parce que votre question sera plus spécifique. – Tobias

Répondre

0

Plutôt que de passer une valeur explicite, passe dans un objet qui crée votre instance pour vous:

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_; 
}; 

Ensuite, votre objet peut avoir son propre créateur spécifique:

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

Le L'avantage de cette approche est que vous pouvez utiliser votre cache avec des objets qui ont différents nombres d'arguments à leurs constructeurs.

+0

merci, votre solution en effet ce dont j'ai besoin, d'autres solutions travaillées mais seulement dans la classe spécifiée, cette approche doit créer CreateInstance dans chaque classe d'objet qui nécessite une mise en cache mais mieux vaut écrire un nouveau template pour chaque classe. –

0

Vous pouvez avoir le paramètre de modèle sur la méthode:

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

Voulez-vous quelque chose comme ça?

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; 
    ... 
} 

est faux. Vous êtes censé indiquer les types utilisés par la classe objectCache. Il devrait être quelque chose comme

objectCache<A, A> intcache; 

Dans la classe objectcache lorsque vous instancier des objets de A, vous devrez passer un paramètre à son constructeur.

Par exemple:

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