Почему new не требует приведения к указателю, даже если это требует malloc? - PullRequest
11 голосов
/ 07 марта 2012

Определение нового в заголовке :

 void* operator new(size_t);

И определение malloc такое, как указано:

 void* malloc(size_t);

Теперь, поскольку C ++ является строго типизированным языком, для преобразования указателя void * в тип, требуемый программистом, требуется приведение от программиста ... В malloc мы должны выполнить приведение, но не в новом, хотя оба возвращают указатель void *. Почему?

Ответы [ 3 ]

12 голосов
/ 07 марта 2012

Потому что, когда вы используете new, вы (обычно) используете «новое выражение», которое выделяет и инициализирует объект. Затем вы назначаете адрес этого объекта указателю на объект того же (или родительского) типа, который не требует приведения. Нормальное новое выражение (т.е. не новое размещение) будет вызывать operator new внутренне, но результатом нового выражения будет , а не только результат от operator new.

Если вы вызываете operator new напрямую, то вам нужно привести его результат, чтобы присвоить возвращаемое значение не пустому указателю, точно так же, как вы должны делать с возвращением из malloc.

5 голосов
/ 07 марта 2012

Потому что у вас неправильное представление о том, как использовать malloc. Он не получает тип в качестве аргумента, а только размер типа.

C и C ++ - это разные языки. В C вам не нужно приводить void* из malloc к целевому типу указателя. В C ++ оператор new глубоко встроен в язык, так что он всегда возвращает значение, соответствующее типу, который вы указали в аргументе.

Правило довольно простое: используйте new для C ++ и malloc для C, не смешивайте их.

1 голос
/ 07 марта 2012

Поскольку вызов operator new - это всего лишь один шаг, генерируемый во всей цепочке при вызове new.

Когда вы делаете s=new my_type(args);, компилятор расширит это до:

s = (my_type*)my_type.operator new(sizeof(my_type));
s.my_type(args); //Constructor call
...