2014-10-13 3 views
1

У меня есть объекты, которые используют перегруженные операторы new/delete, поскольку я использую пулы памяти для выделения их памяти. Они выглядят примерно так:Как распределяет распределитель stl по умолчанию?

class Foo{ 

public: 
    void* operator new(size_t nbytes){ 

     return MemoryManager::GetInstance().AllocFooTypeMemory(); 

    } 
    void operator delete(void* p) 
    { 
     MemoryManager::GetInstance().FreeFooTypeMemory(p); 
    } 

}; 

Теперь мой вопрос, как он тогда работает, когда я создаю STL контейнер указателей Foo? Here написано, что STL по умолчанию Распределителя использований :: Оператора нового выделить память в container.When не использует его? Я попытался увидеть, если Foo-х новый сработал при вызове

std::vector<Foo*> fooVector; 
fooVector.reserve(10); 

, но ничего не происходит ,

У меня есть несколько вопросов:

Правильно ли я в виду, что в этом случае Распределитель выделяет память только для указателей?

Означает ли это, что распределитель вызывает «новое» на Foo, когда контейнер хранит объекты, а не указатели?

Также, если да, значит ли это, тогда мне не нужно писать пользовательский распределитель с пулом mem, если я уже использую пул для выделения памяти в объектах (например, в примере Foo)?

UPDATE:

Для того, чтобы понять, я принимаю во внимание, что только объект, который перегружает новым/удалить с пулом памяти связаны с этой question.i я полностью осознает, что объект, который не имеет нового/удаленная перегрузка по-прежнему использует кучу по умолчанию в качестве источника для распределения динамической памяти.

+0

Нет, вы все еще используете аллокатор по умолчанию с кодом –

+0

Я знаю, что я все еще использую аллокатор по умолчанию, но он будет использовать «новую», чтобы выделить Foo-х? –

+1

Он не будет использовать 'Foo', если вы никогда не скажете ему использовать' Foo'. – tenfour

ответ

7

Распределитель по умолчанию не может использовать класс operator new, , поскольку он не содержит выражения new; он вызывает функцию ::operator new, разделяя выделение и инициализацию .

В вашем случае, конечно, вы не имеете контейнер Foo, но из Foo*, поэтому все, что вы определяете в Foo не имеет значения (и вы не можете определить operator new для указателя).

Что касается ваших конкретных вопросов:

  • В std::vector<Foo*>, вектор будет только выделить указатели. Как он мог сделать что-нибудь еще?

  • Если контейнер содержит Foo, а не Foo*, вопрос сложнее; распределитель по умолчанию будет использовать ::operator new , чтобы выделить память, а ::new (size_t, void*)... - построить объект.

  • Вы не хотите использовать пул памяти для объектов в контейнере . Если контейнер равен std::vector, объекты будут находиться в непрерывной памяти, которые обычно не должны приниматься из бассейна, а для других типов контейнеров то, что выделяется , часто не является Foo, но еще более сложным тип, который содержит Foo.

+0

Итак, это означает, что я должен поставить пользовательский распределитель, чтобы изменить значение по умолчанию :: operator new на перегруженный Foo. Это то, что вы говорите? –

+3

@MichaelIV: Да, за исключением того, что сконструированный контейнер указателей, поэтому Распределитель не используется для выделения 'Foo' объектов на все, что делает спорный вопрос! –

+0

Отлично! Это именно то, что мне нужно было знать. –

0

Завершение работы оператора new и delete в вашем случае применяется только к классу Foo. Это означает, что следующие вызовы используют ваш заказ новых и deleteL:

Foo * p - new Foo(); 
delete p; 

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

+0

См. Мой вопрос. –

Смежные вопросы