Перегрузка новой, удаление в C ++ - PullRequest
4 голосов
/ 03 мая 2010

я наткнулся на эту строчку stroustrup An operator function must either be a member or take at least one argument of a user-defined type (functions redefining the new and delete operators need not).

Не оператор new и оператор delete принимают пользовательский тип в качестве одного из аргументов? что это значит, я что-то здесь упускаю

Ответы [ 4 ]

5 голосов
/ 03 мая 2010

Цитата из Страуструпа, очевидно, относится к перегрузке оператора . Язык C ++ поддерживает перегрузку операторов только для пользовательских типов. Это означает, что функция перегрузки (operator <something>) должна быть либо членом пользовательского типа, либо автономной функцией с хотя бы одним аргументом пользовательского типа. Это именно то, что подразумевается под данной цитатой.

Все же автономные (не являющиеся членами) функции operator new и operator delete не обязаны принимать значение пользовательского типа в качестве одного из своих аргументов. Это может рассматриваться как нечто, противоречащее вашей цитате.

Однако в действительности нет противоречия. Эти операторы на самом деле не перегружены . Когда вы предоставляете свои собственные версии автономных operator new / operator delete, вы на самом деле заменяете библиотечные. Это официальный термин из спецификации языка: замена , а не перегрузка . Вот почему приведенная выше цитата не относится к operator new и operator delete.

3 голосов
/ 03 мая 2010

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

2 голосов
/ 03 мая 2010

a + b - это просто синтаксический сахар для a.operator+(b) или operator+(a, b).

С другой стороны, new Foo(x, y, z) - это НЕ просто синтаксический сахар для operator new(Foo, x, y, z) или что-то в этом роде. Это намного сложнее:

void* address = operator new(sizeof(Foo)); // here is the behavior you can replace
try {
    new(address) Foo(x, y, z);
} catch (...) {
    operator delete(address);
}

Как видите, функция operator new просто выделяет память, что составляет лишь половину того, что фактически делает оператор new. На мой взгляд, было бы гораздо разумнее назвать эту вещь allocate_memory или что-то в этом роде. Это определенно НЕ оператор, как operator+.

0 голосов
/ 03 мая 2010

operator new и operator delete ищутся на основе типа операнда в выражении new или delete и любых дополнительных аргументов в скобках для new. Таким образом, они могут быть перегружены (и operator new является подверженным разрешению перегрузки), но другим механизмом, чем другие операторы. (C ++ 03 §13.5 / 5)

Поскольку они работают с необработанной памятью, они никогда не имеют дело с указателями на тип класса клиента. operator new всегда принимает аргумент size_t (и, возможно, другие аргументы, ни один из которых не должен быть пользовательского типа) и возвращает void *. operator delete всегда принимает аргумент void * и, необязательно, size_t, независимо от того, как он был найден.

Я могу придумать две причины для этого:

  • Они имеют дело с необработанной памятью, не содержащей построенный объект. Для operator new или operator delete всегда возникает ошибка при попытке получить доступ к объекту в возвращенном блоке памяти. (Память не , используемая для построения объектов, однако, является честной игрой.)
  • Член класса operator new или operator delete может иметь множественное и / или виртуальное наследование, так что рассматриваемый void* не может указывать на еще не построенный или уже разрушенный подобъект любым вуду.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...