「新しいオペレーター」と「新しいオペレーター」の違いは何ですか?


126

「新しいオペレーター」と「新しいオペレーター」の違いは何ですか?


3
こんにちは、質問を明確にしていただけますか?どこかにタイプミスがあるようです。
Dima Malenko、

17
質問は正しく記述されています。以下の回答を参照してください。動的にメモリを割り当てる方法は、new演算子を使用することです。この演算子はオーバーロードされる可能性があります。デフォルトのオペレーターとオーバーロードされたバージョンを区別するために、デフォルトは「新しいオペレーター」と呼ばれ、オーバーロードされたバージョンは「オペレーターnew」と呼ばれます。
Thomas Matthews

2
どうやってするか。私は新しくて気づいていません。
Sandeep、

回答:


127

私は通常、2つを少し上手に区別するために別の言い方をするようにしていますが、いずれにしても良い質問です。

演算子newは、生のメモリを割り当てる関数です。少なくとも概念的には、と大差ありませんmalloc()。独自のコンテナのようなものを書いていない限り、これはかなり珍しいことですが、次のように直接operator newを呼び出すことができます。

char *x = static_cast<char *>(operator new(100));

演算子newをグローバルに、または特定のクラスにオーバーロードすることもできます。IIRC、署名は次のとおりです。

void *operator new(size_t);

もちろん、演算子new(グローバルまたはクラスのいずれか)をオーバーロードする場合、一致する演算子の削除もオーバーロードする必要があります。価値のあるものとして、配列にメモリを割り当てるために使用される別の演算子new []もありますが、ほとんどの場合、混乱を完全に無視する方がベターです。

新しい演算子は、無料ストアからオブジェクトを作成するために通常使用するものです。

my_class *x = new my_class(0);

2つの違いは、演算子newがrawメモリを割り当てるだけで、それ以外には何もないということです。new演算子は、operator newを使用してメモリを割り当てることから始まりますが、適切なタイプのオブジェクトのコンストラクターを呼び出すため、結果はそのメモリ内に作成された実際のライブオブジェクトになります。そのオブジェクトに他のオブジェクトが含まれている場合(埋め込みクラスまたは基本クラスとして)、それらのコンストラクターも呼び出されます。


18
+1、別の言い回しに関しては、標準は新しい式をすべての場所で使用し、新しい演算子を使用して呼び出しの場所を参照するのは一度だけです。私は同じことをする傾向があります:アロケーターのための新しい演算子と使用のための新しい式
デビッドロドリゲス-11

3
新しい表現とは、newで始まるフレーズ全体です。では、その「新しい」部分だけを何と呼びますか?新しい演算子を呼び出すのが間違っている場合は、sizeof演算子の「sizeof」や、(演算子のように動作する場合は)&アドレス演算子を呼び出さないでください。
Kaz

1
Kazの発言に続いて、おそらく質問は、「newオペレーターとoperator newオペレーターの違いは何ですか?」と言い換える必要があります。:)
CS

2
「新しいオペレーター」対「新しいキーワード」
user997112 14

2
@antred:あなたはのようなものでそれをリリースするでしょうoperator delete(x);
Jerry Coffin 2014年

35

「新しいオペレーター」

class Foo
{
public:
        void* operator new( size_t );
}

「新しいオペレーター」:

Foo* foo = new Foo();

この例でnew Foo()は、Foo::operator new()

つまり、operator new()+演算子が呼び出すのと同じように、「新しい演算子」が「」を呼び出しますoperator +()


13
newC ++では演算子ではありません。sizeofたとえば、は演算子ですがnew、そうでdeleteはありません。newおよびdeleteはキーワードであり、これらのキーワードによって形成される構文構造は、new-expressionおよびdelete-expressionと呼ばれます
AnT 2009

2
ええと、どちらかといえばsizeof構文構文でありnewdelete両方とも有効で合法なオーバーロード可能な演算子です。私が今まで見たすべてのものから、newそしてdelete両方ともオペレーターです。[cplusplus.com] [ cplusplus.com/doc/tutorial/classes2/]を
オースティンハイド

7
不正解です。公式のC ++用語は、言語仕様によって定義された用語であり、一部のWebサイトでは定義されていません。言語仕様には「新しい演算子」などの用語はありませんが、「operator new関数」などの用語があります。ここでも、sizeof一方でexplicilty、「オペレータ」と呼ばれているnewdeleteされている決してオペレーターと呼ばれていません。
AnT 2009

6
AndreyT:不正解です。C ++標準は「新しい」演算子を呼び出します。13.5/ 1を参照してください。

3
@AndreyT:あなたがそうであるように、その演算子newアロケータであり、new-expressionは使用法だと思いました。5.3.4 / 3では、現在の標準で新しい演算子という用語が使用されていることを確認して確認しました。その後として§5.3.4/ 8それ名称アロケータ機能でオペレータ新しいオペレータ新しい[]
dribeas -デビッド・ロドリゲス

22

以下は、スコット・マイヤーズのより効果的なC ++の本からの引用です。

new演算子は、必要なメモリ割り当てを実行する関数を呼び出し、その関数を書き換えまたはオーバーロードして、その動作を変更できます。newオペレーターがメモリを割り当てるために呼び出す関数の名前はoperator newです。


7
用語は明らかにその本の著者によって発明された(または、おそらく、いくつかの古いソースから借りられた)。正式なC ++の命名法では、「新しい演算子」などの用語はありません。
AnT 2009

2
@AndreyT:C ++ 11で「新しい演算子」を検索したところ、4つの場所で参照されていることがわかりました。具体的には、「placement new operator」への2つの参照
Mooing Duck、2015

11

「新しいオペレーター」と「新しいオペレーター」の間に違いはありません。どちらも同じことを指しoperator newます。通常、new-expressionsによって作成されたオブジェクトに未加工のメモリ割り当てを実行するオーバーロード可能/置換可能関数です。

また、どちらの用語も言語仕様には含まれていないことに注意してください(公式用語の定義ソースです)。

あなたが使用する場合はnew、オブジェクトを作成するために、あなたのプログラムでは、それが呼ばれる新しい表現new-expressionは、キーワードnewと、文法で定義された追加の構文部分で構成されます。この式の構文のどの部分も「演算子」と呼ばれることはありません。

生のメモリ割り当て関数operator newは、正式には単に「operator new関数」と呼ばれます。このシーケンスの単語operatornewは、2つの別個のC ++言語キーワードにすぎないことに注意してください。彼らは英語の用語「オペレーター新」を形成しません。言語仕様のどこにも、英語の用語としての「operator new」への言及はありません。これは毎回、メモリ割り当て関数の宣言構文を生成する2つの独立したキーワードの組み合わせです。

繰り返しになりますが、正式にはC ++には、「operator new」や「new operator」などの英語の用語はありません。前者のシーケンスは、英語の用語としてではなく、単なるキーワードの組み合わせとして言語仕様に存在します。後者はまったく存在しません。


14
あなたはいくつかの穏やかな精神的マスターベーションで迷っているようです。基準はスポットで曖昧であり、これはそれらの1つです。「新しい演算子について話し合う」ことは、「プラス演算子について話し合う」または「+演算子について話し合う」ことと同じくらい意味があります。

7

新しいオブジェクトを作成すると、メモリはoperator newを使用して割り当てられ、コンストラクタが呼び出されてメモリが初期化されます新しいオペレータが割り当てと、オペレータが新しいだけ割り当てと同様に初期化、の両方を行います。


6

OPの質問は適切に表現されていません。「新しいオペレーター」と「新しい表現」の違いを段階的に示した方がいいですか?「オペレーターの新しい」はしばしば「オペレーターの新しい機能」も指します。

そして、周りにはたくさんの正しい答えがあります、以下は私のものです:

1> 'new expression'は 'operator new'を呼び出してrawメモリを割り当て、次にコンストラクタを呼び出します

apple * p = new apple(); //new expression

2> 'operator new'はrawメモリのみを割り当て、mallocとの違いはあまりありません

void* mem = operator new(sizeof(apple)); //just like calling malloc()
apple* p2 = new(mem) apple(1); //call construct here using placement new.

2

新しい演算子:C ++は、新しい演算子を使用したオブジェクトの動的割り当てをサポートしています。新しいオペレーターは、フリーストアと呼ばれるプールからオブジェクトにメモリを割り当てます。new演算子は、特殊関数演算子newを呼び出します。

operator new:要求が0バイトのストレージに対するものである場合、operator newは別個のオブジェクトへのポインターを返します(つまり、operator newを繰り返し呼び出すと、別のポインターが返されます)。割り当て要求に十分なメモリがない場合、オペレーターnewはNULLを返すか、例外をスローします。operator newの最初の引数は、size_t型(STDDEF.Hで定義されている型)である必要があり、戻り値の型は常にvoid *です。

詳細については、MSDNリンクを以下に示します。

オペレーターの新しい関数

新しいオペレーター


1
若干の明確化:非配置演算子newは常に(標準に従って)割り当て失敗をスローする必要があります。およびなどの配置フォーム::new(std::nothrow)はどちらも実行できます(この特定の例ではnullポインターを返します)。

1
  1. newは演算子であり、キーワードでもあります。

    [1] 2.13および&2.12を参照してください。

  2. newは2つのことを行います。T* t = new T(arg);

    1)オブジェクトにメモリを割り当てます:void * ptr = operator new(sizeof(T));

    // 演算子newは関数(cのmallocと同じ)であり、演算子ではありません(3.7.4の[1]を参照)。しかし、項目7 [2]もオペレーターであると述べています。私の意見では、演算子と関数の違いは小さく、演算子のオーバーロードは関数によって実装されていることを思い出すとわかります。

    //ここで必要な処理を実行するこのoperator / function(operator new)をオーバーロードできます。

    2)割り当てられたメモリ内のオブジェクトを初期化:ptrでT :: T(arg)を呼び出します

    // コンパイラのみがこれを行うことができます。私もあなたもできません。

    // Tにメンバーオブジェクトのコンストラクターと基本クラスのコンストラクターがある場合、コンパイラーもそれらを呼び出します。そして、この呼び出しは再帰的です。コンパイラだけがそれを行うことができます。

  3. したがって、オペレーターnewはnewのミッションの一部を実行し、この部分でのみ、何かを実行できます。

    [1]:ISO / IEC、N3690。http://ww.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf

    [2]:マイヤーズ、スコット。効果的なC ++、3番目。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.