web-dev-qa-db-ja.com

なぜ通常の関数ではなく、非配置の「new」と「delete」が言語に組み込まれているのですか?

なぜ非配置 new expressiondelete expression は通常の関数の代わりに言語組み込みとして実装されたのですか?

もしあれば...

  • oSにメモリをリクエスト/提供する方法

  • コンストラクターを明示的に呼び出す方法(placement 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 */
} 
38
Vittorio Romeo

ユーザーの目標がメモリの場所にオブジェクトを作成することだった場合、newは、転送参照variadic templatesおよびplacement newは当時のものではありませんでした。 @ T.C。 によって正しく指摘されているように、テンプレートは1990年にリリースされ、1989年に新しい配置になりました。

tl; dr引数の束を任意の型のコンストラクターに転送する方法はありませんでした(最近のmake関数でできるように)。

26
Curious

たぶんこれは最良のリファレンスではありませんが、これはウィキペディアが言っていることです placement new

C++の以前のバージョンでは、placement new;のようなものはありませんでした。代わりに、開発者はコンストラクタ内でthisへの明示的な割り当てを使用して、同様の効果を実現しました。この方法は廃止され、後ほど廃止され、The "C++ Programming Language"の第3版ではこの手法について言及されていません。 placement new演算子のサポートが1995年頃のコンパイラに追加されました。

たぶん2017年にnewを標準ライブラリ関数として実装することが可能になるかもしれません。推奨される実装では、最近追加された言語機能を使用します(多くは2010年以降)。

ただし、C++言語はずっと古く(1983年以降)、最初は可変テンプレート、typename、配置new、転送参照はありませんでした。

当初は、通常のnewのみがあり、ライブラリ関数として実装する方法がなかったため、当時は言語機能でなければなりませんでした。

14
axiac

それらが既にスタンドアロン関数として提供されている場合、ユーザー定義の代替を提供することは不可能です。

例えば現在、標準によれば、自分のglobl newdeleteを書くことは、プログラム全体で使用されます。

18.6.2ストレージの割り当てと割り当て解除[new.delete]

2置換可能:C++プログラムは、これらの関数シグネチャのいずれかを使用して関数を定義し、C++標準ライブラリで定義されているデフォルトバージョンを置き換えることができます。

これらが他のライブラリ関数と同じように提供された場合、newまたはdeleteへの通常の呼び出しはすべて、「オーバーロードされた関数の複数のインスタンスが引数に一致する」エラーになります。

4
VTT