Перегрузка новой функции в качестве друга? - PullRequest
0 голосов
/ 27 ноября 2010

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

template<typename T, unsigned int N>
class MemoryPool
{
    //Stuff
};

Где T - класс, для которого создается этот пул, а N - максимальное количество элементов, которые могут быть помещены в пул.Я хочу перегрузить new для созданного типа, чтобы немного облегчить взаимодействие с пулом, если это разумно, но я не уверен, что это так.

Мои мысли в настоящее времяв том, что если возможно перегрузить new как функцию друга для T в MemoryPool, то это должно быть выполнимым оттуда, но я не уверен.И я не уверен, что лучший способ начать это настраивать.Я пробовал несколько разных способов просто объявить перегруженный new, и я получаю ошибки, прежде чем даже реализовать его.

  • Это разумный способ убедиться, что new переопределяется длялюбой класс, который использует MemoryPool?
  • Возможно ли это сделать?
  • Это даже хорошая идея?
  • Как я бы настроил объявление функции для достижения этой цели?

В случае, если этоимеет значение, я использую Visual Studio 2010.

Обратите внимание, что использование шаблонов и перегрузка new не являются частью домашнего задания.Это просто, как я хочу реализовать это, если это возможно, чтобы облегчить чтение остальной части задания в будущем.Итак, если нет разумного способа сделать это, я просто использую функции-члены в MemoryPool для достижения той же цели.

Спасибо!

Пример реализации:

MemoryPool<Object, MAX_OBJECTS> objectPool;  //Pool to store objects
Object*  allObjects[MAX_OBJECTS];            //Locations of objects

//Make a new object (this is how I'd like to do it)
allObjects[0] = new Object(/*args*/);

//(If I can't do the above, this would be the alternative)
allObjects[0] = objectPool.AllocateNewSlot();
allObjects[0]->Initialize(/*args*/);

В этом примере использование MemoryPool позаботится о фактической реализации new, обеспечивающей создание Объекта в его пуле, а не где-нибудь в куче (чтобы гарантировать, что все Объекты находятся в централизованном, болееконтролируемое местоположение.

1 Ответ

2 голосов
/ 27 ноября 2010

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

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

Вот что вы могли бы сделать.

template<typename T, unsigned int N>
class MemoryPool
{
    T* malloc()
    {
        return ... // your pool impl
    }

    void free(T* ptr)
    {
        ... // your pool impl
    }

    void destory(T* ptr)
    {
        ptr->T::~T(); // call destructor
        free(ptr);
    }
};

int main()
{
    MemoryPool<my_class> pool;
    my_class* instance = new (pool.malloc()) my_class(/*args*/); // in-place new
    return 0;
}

Вы также должны взглянуть на то, как реализован пул повышения .

...