0

理解できない問題があります。

class Systemいくつかのメンバーフィールドを持つがあり、そのうちの1つがタイプであるとしましょうunordered_map。したがって、ヘッダーファイルでクラスを宣言するときは、ヘッダーの先頭に書き込みます#include <unordered_map>

現在、このフィールドを宣言する方法は2つあります。

1.std::unordered_map<std::string,int> umap;
2.std::unordered_map<std::string,int>* p_umap;

クラスのコンストラクターで、最初のオプションを選択した場合、のコンストラクターはタイプのインスタンスの構築の一部としてclass Systemフィールドのデフォルトコンストラクターを呼び出すため、初期化子リストでそのフィールドを初期化する必要はありません。umapclass System

2番目のオプションを選択した場合、p_umapこの動的割り当てを削除するには、コンストラクター(初期化リスト内)のフィールドを演算子newおよびデストラクタで初期化する必要があります。

これら2つのオプションの違いは何ですか?フィールドの1つがタイプであるクラスがある場合、unordered_mapこのフィールドをどのように宣言しますか?ポインタとして、または型の変数としてunordered_map

4

4 に答える 4

5

あなたが説明しているような状況では、最初のオプションが望ましいようです。実際、順序付けされていないマップは、それがデータ メンバーであるクラスによって所有されることを意図している可能性が最も高いです。つまり、その有効期間は、カプセル化クラスの有効期間を超えて延長されるべきではなく、カプセル化クラスには、順序付けられていないマップの作成と破棄の責任があります。

オプション 1 ではこの作業はすべて自動的に行われますが、オプション 2 では手動で処理する必要があります (正しいコピー構築、コピー割り当て、例外安全性、メモリ リークの欠如などを処理します)。 . 確かに、スマート ポインター (例: ) を使用して、この責任をラッパーにカプセル化して、スマート ポインター自体が範囲外になったときにラップされたオブジェクトを削除することもできます (このイディオムは RAII と呼ばれ、 Resource Acquisition Is Initializationstd::unique_ptr<>の頭字語です)。)。

ただし、ここではポインターはまったく必要ないように思えます。オブジェクトを含むクラスのライフタイムによってライフタイムが完全に制限されているオブジェクトがあります。このような状況では、ポインターを使用せず、変数を次のように宣言することをお勧めします。

std::unordered_map<std::string, int> umap;
于 2013-03-19T19:43:23.777 に答える
2

ポインターにする必要があるまで、ポインターを非ポインターにします。

ポインターにはユーザー エラーがはびこっています。

たとえば、class System実装する必要があることを忘れていました

System( const Sysytem& )

System& operator= ( const System& )

または、オブジェクトをコピーしようとすると、悪い動作が発生します。

于 2013-03-19T19:42:51.257 に答える
0

違いは、umap にアクセスできるようにする方法にあります。ポインタを使用すると、もう少し柔軟に対応できますが、明らかに割り当てに関して複雑さが増します (スタックとヒープ、デストラクタなど)。umap へのポインターを使用すると、同じ umap で 2 つのシステムを作成するなど、かなり複雑なことができます。ただし、やむを得ない理由がない限り、KISS を使用してください。

于 2013-03-19T19:43:43.400 に答える
0

ポインタとして定義する必要はありません。その場合は、コピー コンストラクターと代入演算子も実装するか、完全に無効にする必要があります。

ポインターにする特別な理由がない場合 (そして何も表示しない場合) は、通常のメンバー変数にします。

于 2013-03-19T19:44:14.650 に答える