web-dev-qa-db-ja.com

C ++で「新規」を使用する場合と使用しない場合

可能性のある複製:
C++で新しいキーワードを使用する必要があるのはいつですか?

C++で「新しい」演算子を使用する必要があるのはいつですか?私はC#/ Javaのバックグラウンドから来ており、オブジェクトのインスタンス化は混乱を招きます。

「ポイント」という単純なクラスを作成した場合、ポイントを作成するときに次のことを行う必要があります。

Point p1 = Point(0,0);

または

Point* p1 = new Point(0, 0);

誰かが新しい演算子を使用する場合と使用しない場合を明確にすることはできますか?

重複:

C++で新しいキーワードを使用する必要があるのはいつですか?

関連:

カスタムオブジェクト用のC++のコンストラクタ/デストラクタおよびnew/delete演算子について

C++での適切なスタックとヒープの使用法

97
Frankenstein

オブジェクトをnewするまで存在させたい場合は、deleteを使用する必要があります。 newを使用しない場合、オブジェクトはスコープ外になると破棄されます。これのいくつかの例は次のとおりです:

void foo()
{
  Point p = Point(0,0);
} // p is now destroyed.

for (...)
{
  Point p = Point(0,0);
} // p is destroyed after each loop

一部の人々は、newの使用がオブジェクトがヒープ上にあるかスタック上にあるかを決定すると言うでしょうが、それは関数内で宣言された変数にのみ当てはまります。

以下の例では、 'p'の場所は、それを含むオブジェクトFooが割り当てられる場所になります。これを「インプレース」割り当てと呼びます。

class Foo
{

  Point p;
}; // p will be automatically destroyed when foo is.

newを使用したオブジェクトの割り当て(および解放)は、インプレースで割り当てられた場合よりもはるかに高価になるため、必要に応じて使用を制限する必要があります。

newを介して割り当てる場合の2番目の例は、配列の場合です。実行時にインプレースアレイまたはスタックアレイのサイズを変更することはできないため、未定サイズのアレイが必要な場合は、newを介して割り当てる必要があります。

例えば。

void foo(int size)
{
   Point* pointArray = new Point[size];
   ...
   delete [] pointArray;
}

(*プリエンプティブnitpicking-はい、可変サイズのスタック割り当てを許可する拡張機能があります)。

131
Andrew Grant

C++オブジェクトのインスタンス化に関する適切な回答については、 この質問 および この質問 をご覧ください。

この基本的な考え方は、(newを使用して)ヒープ上でインスタンス化されたオブジェクトは手動でクリーンアップする必要があり、(newなしで)スタック上でインスタンス化されたオブジェクトはスコープ外になると自動的にクリーンアップされるということです。

void SomeFunc()
{
    Point p1 = Point(0,0);
} // p1 is automatically freed

void SomeFunc2()
{
    Point *p1 = new Point(0,0);
    delete p1; // p1 is leaked unless it gets deleted
}
8
Eclipse

スタックではなくヒープ上にオブジェクトを作成する場合は、newを使用する必要があります。これにより、ポインターを使用して、現在の関数またはプロシージャの外部からオブジェクトにアクセスできます。

C++でポインタとメモリ管理を調べるのは、他の言語では出会う可能性が低いため、役に立つかもしれません。

4
AAA

Newは常に動的メモリを割り当てるために使用され、その後、解放する必要があります。

最初のオプションを実行すると、スコープが失われたときにそのメモリが自動的に解放されます。

Point p1 = Point(0,0); //This is if you want to be safe and don't want to keep the memory outside this function.

Point* p2 = new Point(0, 0); //This must be freed manually. with...
delete p2;
1
Lomilar