1

ヒープ上にオブジェクトを構築することは、C++ 言語では一見単純に見えるタスクです。コードが

T* object = new T();
func(object);

が呼び出された場合、メモリを最初に割り当ててから初期化し、最後にクラスのコンストラクターを呼び出す必要があることを理解しています。さらに、オブジェクトの仮想テーブルは、構築が完了するまで必ずしも使用できるとは限りません。

私の質問は次のとおりです。完全に構築されていないオブジェクトoperator newで動作するように、オブジェクトの構築が完了する前に、割り当てられた/初期化されたメモリへのポインターを返すことができますか? func(...)この質問に対する答えは、私が開発中のマルチスレッド ライブラリに影響を与えます。

前もって感謝します。

4

4 に答える 4

6

operator newメモリを割り当てます。キーワード(newサンプル コードで使用) を使用operator newしてメモリを割り当て、そのメモリ内にオブジェクトを構築します。そして、はい、適切な同期のないマルチスレッド アプリケーションでは、コンストラクターの副作用が発生する前に、ポインター値が他のスレッドで表示される可能性があります。これは、各プロセッサが個別のキャッシュを持つことができ、コンストラクターの副作用がキャッシュに読み込まれる前にポインター値がキャッシュに読み込まれる可能性があるためです。詳細については、「ダブルチェック ロック」を参照してください。

于 2013-06-26T13:41:41.587 に答える
1

object、構築が行われる前にオブジェクトを指すことはありません。new T()完成するまで帰ってこない。

ピート・ベッカーはキャッシュの問題で正しいと思いますが...

于 2013-06-26T13:41:42.870 に答える
0

メモリは最初に割り当ててから初期化し、最後にクラスのコンストラクタを呼び出す必要があります。

中段はわかりません。フォームoperator newが呼び出された後、前者によって返されたメモリのコンストラクターが呼び出されます。

さらに、オブジェクトの仮想テーブルは、構築が完了するまで必ずしも使用できるとは限りません。

それは利用可能です -- ある意味で (標準は VMT をまったく義務付けておらず、動作のみを要求しています)、簡単に言えば、構築中のクラスは、アクティブな ctor の「最も派生した」クラスであるかのように動作します。仮想呼び出しを発行することはできますが、それらは Base::Base() から Base::foo に到達します。init リストから呼び出された場合、一部の部分がまだ構築されていないことに注意する必要があります。

私の質問は次のとおりです:オブジェクトの構築が完了する前に、新しい演算子は割り当てられた/初期化されたメモリへのポインターを返すことができますか?

operator new ctor が開始される前に常に実行され、終了します。

new operatorしかし、あなたはあなたの質問のように意味するかもしれません. これは、すべてが完了したときにのみ返され、ctor はその仕事を完了しました。

于 2013-06-26T13:42:59.013 に答える