Почему новый не требует приведения к указателю, хотя это требует 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