Конструктор класса в шаблоне

У меня есть класс кеша объектов, подобный этому:

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

Я знал, что «typename type2» не нужен, но мне нужен способ передать объект класса, у которого есть конструктор с параметром, таким как класс A, в шаблон. или их был другой способ сделать это? пожалуйста помоги.


person Nhu Phuong    schedule 21.07.2009    source источник
comment
Можете ли вы объяснить словами, чего вы пытаетесь достичь с помощью класса objectCache? Таким образом, читателям не придется дизассемблировать эту информацию из вашего кода; и вы можете получить лучшие ответы, потому что ваш вопрос будет более конкретным.   -  person Tobias    schedule 21.07.2009


Ответы (4)


Вместо того, чтобы передавать явное значение, передайте объект, который создает для вас ваш экземпляр:

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

Тогда ваш объект может иметь своего конкретного создателя:

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

Преимущество этого подхода в том, что вы можете использовать свой кеш с объектами, которые имеют разное количество аргументов для своих конструкторов.

person Richard Corden    schedule 21.07.2009
comment
спасибо, ваше решение действительно то, что мне нужно, другие решения работали, но только в указанном классе, этот подход требует создания CreateInstance в каждом классе объектов, который необходимо кэшировать, но это все же лучше, чем писать новый шаблон для каждого класса, который необходимо кэшировать. - person Nhu Phuong; 21.07.2009

Вы хотите что-то вроде этого?

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;
}
person Kirill V. Lyadvinsky    schedule 21.07.2009

Вы можете иметь параметр шаблона в методе:

template <typename type2>
type1* objectCache::Get()
person Edouard A.    schedule 21.07.2009

int main(int argc, char* argv[])
{    
    objectCache<a, a(1)> intcache;
    ...
}

неправильно. Вы должны указать типы, используемые классом objectCache. Это должно быть что-то вроде

objectCache<A, A> intcache;

В классе objectCache, когда вы создаете экземпляры объектов A, вам нужно будет передать параметр его конструктору.

Например:

...
type1 * temp = new type1(1);
...    
person Indy9000    schedule 21.07.2009