Почему не помещаются слова `new` и` delete`, встроенные в язык, а не только обычные функции?
Почему не было размещения new
выражение и delete
выражение реализовано как встроенный язык вместо обычных функций?
Если у нас есть...
-
способ запроса/возврата памяти в ОС
-
способ явного вызова конструктора (размещение new
)
-
способ явно вызвать деструктор (~T()
)
... почему нельзя было не размещать new
и delete
только регулярные функции в стандартной библиотеке? Пример:
template <typename T, typename... Ts>
T* library_new(Ts&&... xs)
{
auto* ptr = /* request enough memory for `T` from OS */;
new (ptr) T(std::forward<Ts>(xs)...);
return ptr;
}
template <typename T>
void library_delete(T* ptr)
{
ptr->~T();
/* reclaim memory for `T` from OS */
}
Ответы
Ответ 1
Если целью пользователя было создание объекта в некоторой ячейке памяти, тогда new
выглядел как естественный подход, поскольку ссылки пересылки, вариативные шаблоны и размещение новых не было в те дни. Как правильно отметили @TC шаблоны были выпущены в 1990 году и были размещены новыми в 1989 году. Шаблоны Variadic, с другой стороны, стали частью С++ только в С++ 11.
tl; dr Невозможно перенаправить кучу аргументов в конструктор произвольного типа (как вы можете в эти дни с функциями make
).
Ответ 2
Возможно, это не лучшая ссылка, но это то, что Wikipedia говорит о размещения new
в С++:
В более ранних версиях С++ не было такой вещи, как размещение new; вместо этого разработчики использовали явное назначение this
внутри конструкторов для достижения аналогичного эффекта. Эта практика устарела и отменена позже, а в третьем издании "Язык программирования С++" не упоминается этот метод. Поддержка размещения нового оператора была добавлена к компиляторам примерно в 1995 году.
Возможно, в 2017 году можно реализовать new
как стандартную библиотечную функцию. В предлагаемой реализации реализованы языковые функции, которые были добавлены недавно (многие из них после 2010 года).
Язык С++, однако, намного старше (с 1983 года), и в начале не было никаких вариационных шаблонов, нет typename
, нет места размещения new
, нет ссылок на пересылку.
В начале был только обычный new
, и в то время он должен был быть языковой функцией, потому что не было возможности реализовать его как библиотечную функцию.
Ответ 3
Если они уже были предоставлены как автономные функции, тогда было бы невозможно предоставить им определенную пользователем замену.
например. прямо сейчас в соответствии со стандартом Legel, чтобы написать свой собственный globl new
и delete
, они будут использоваться по всей программе.
18.6.2 Распределение и освобождение памяти [new.delete]
2 Сменные: программа на С++ может определять функции с любой из этих сигнатур функций и тем самым вытеснять версии по умолчанию, определенные стандартной библиотекой С++.
Если они были предоставлены так же, как и остальные функции библиотеки, каждый обычный вызов new
или delete
привел бы к ошибке "более одного экземпляра перегруженной функции соответствует аргументам".