Почему новый не требует приведения к указателю, хотя это требует malloc?
Определение нового в заголовке <new> :
void* operator new(size_t);
И определение malloc как указано:
void* malloc(size_t);
Теперь, когда С++ является строго типизированным языком, для него требуется бросок от программиста, чтобы преобразовать указатель void * в тип, который требуется программисту... В malloc нам нужно выполнить бросок, но не в новом, хотя оба возвращают указатель void *. Почему?
Ответы
Ответ 1
Потому что, когда вы используете new
, вы (обычно) используете "новое выражение", которое выделяет и инициализирует объект. Затем вы назначаете адрес этого объекта указателю на объект того же (или родительского) типа, который не требует приведения. Нормальное новое выражение (т.е. Не новое место размещения) будет вызывать operator new
внутренне, но результат нового выражения является не только результатом от operator new
.
Если вы вызываете operator new
напрямую, тогда вам нужно указать результат, чтобы присвоить возвращаемое значение указателю не-void, точно так же, как вы должны сделать с возвратом из malloc
.
Ответ 2
Потому что у вас неправильное представление о том, как использовать malloc
. Он не получает тип в качестве аргумента, а только размер этого типа.
C и С++ - разные языки. В C вам не нужно указывать void*
malloc
на тип целевого указателя. В С++ оператор new
глубоко встроен в язык, так что он всегда возвращает значение, соответствующее типу, указанному в аргументе.
Правило довольно простое использование new
для С++ и malloc
для C, не смешивайте их.
Ответ 3
Потому что вызов operator new
- это всего лишь один шаг, сгенерированный во всей цепочке при вызове new
.
Когда вы выполняете s=new my_type(args);
, компилятор расширит его, чтобы:
s = (my_type*)my_type.operator new(sizeof(my_type));
s.my_type(args); //Constructor call