2013-04-29 4 views
2

я прошел через перегрузку нового и удалить, я читал в книге о том, что разница между новой и таНосом является то, что новый вызов конструктора, возвращает тип вызова переменного, а третье отличие заключается в том, что мы можем перегрузить новый на класс за классом, тогда как malloc не может быть, может кто-то объяснить этот класс за счет класса также.Можем ли мы перегружать malloc()?

+0

'мы можем перегрузить новый класс по классам' - все это означает, что вы можете настроить конструктор для каждого типа. –

+0

ОК, а как насчет malloc ?? –

+0

Можем ли мы сделать то же самое с malloc, я имею в виду перегрузку malloc() как функцию, потому что я не понимаю, почему это было написано в книге, что мы не можем? –

ответ

4

::operator new в глобальном пространстве имен можно заменить (переопределить), а не перегружать. Это приводит к тому, что переопределение используется вместо функции, предоставляемой стандартной библиотекой. И может быть предоставлен my_class::operator new, поэтому он будет использоваться в выражениях new my_class, который также отличается от перегрузки.

Перегрузка new только вступает в игру, когда вы используете размещение new синтаксис:

new (memory_pool, 123, other_args) my_class(constructor_args) 

Предоставления дополнительных аргументов в круглых скобках после new ключевого слова вызывает другую перегрузку operator new называть, с дополнительными аргументами прилагаемых после size_t с указанием объема памяти.

Вы можете, конечно, перегружать ::malloc так же, как и любой другой функции, определяя версию, которая принимает различные аргументы:

void *malloc(std::size_t size, allocation_pool &pool); 

Это просто новая функция, которая происходит называться malloc. Но лучше назвать библиотечные функции явной квалификацией std::, и добавление перегрузки std::malloc будет противоречить правилам библиотеки.

Вы не можете заменить std::malloc. Единственными функциями, которые можно заменить, являются стандартные варианты ::operator new. Нет такой вещи, как класс-malloc, потому что она не принимает аргумент, указывающий, какой класс войдет в блок возвращенной памяти. malloc не знает, что вы будете делать с возвращенной памятью; это просто капля байтов.

В связи с организацией программы, вероятно, следует назначить более специализированный распределитель и назвать его другим именем, а не malloc. Если вам нужно вызывать разные функции в зависимости от типа, используйте шаблон, например.

template< typename allocated > 
void *my_allocate(std::size_t sz); // maybe "sz" param is unnecessary. 

Вы также можете специализироваться std::allocator<my_class> и его член функции allocate. Тогда различные стандартные библиотеки будут вызывать вашу функцию, несмотря на отсутствие настройки new. (Из-за своих причуд вы можете избежать слишком глубокого использования в пользовательских new.)

2

Перегрузка new не имеет отношения к constructors. A class может предоставить собственный оператор new(), который отвечает за выделение памяти перед вызовом конструктора. Это полезно для оптимизации пулов небольших объектов, например. Вы также можете изучить различные перегрузки оператора new(), в том числе так называемое «размещение нового», позволяющее произвольные аргументы поставляться для таких вещей, как построение на месте (пользовательский буфер), диагностика файлов/строк и т. Д.

+0

ok, поэтому я думаю, что ответ таков: для случая * new *, поскольку перегрузка может быть полезна в тех случаях, когда мы знаем размер, который нужно выделить, так как он также будет создавать объект. Но в * malloc * мы не можем иметь такое же преимущество, как * malloc * ограничивается только распределением памяти, поэтому нам не нужно перегружать * malloc *, нет необходимости и пользы от этого. –

+0

@Praveen - это правильно, malloc - «тип-меньше», возвращая только пустоту *, поэтому на самом деле нет оснований для перегрузки. –

1

Да, мы можем перегружать стандартную библиотечную функцию malloc. Пожалуйста, смотрите на фрагменте кода ниже:

#include <iostream> 
    void malloc(void) 
    { 
     puts("malloc"); 
    } 

    int main() 
    { 
     int *p= (int*)malloc(8); 
     malloc(); 
     free(p); 
     return 0; 
    } 

Этот код печатает таНос.

Кроме того, Ниже приведен фрагмент текст секции памяти для этой программы:

0000000000400744 T _Z6mallocv 
    0000000000400770 T main 

и Ниже приведен фрагмент из ДИНАМИЧНОГО SYMBOL TABLE

0000000000000000  DF *UND* 00000000000001d2 GLIBC_2.2.5 malloc 
    0000000000000000  DF *UND* 00000000000001a5 GLIBC_2.2.5 __libc_start_main 

Следовательно, мы можем перегружать стандарт библиотечные функции, такие как malloc в C++.

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