デフォルト コンストラクターからオーバーロードされたコンストラクターを呼び出すときにオブジェクトの状態情報を維持する
-
21-12-2019 - |
質問
その質問のタイトルは一口にすぎません。基本的に、ベクトル内の二重リンクリストを使用するハッシュテーブル構造を作成しています。オーバーロードされたコンストラクターを使用してオブジェクトを作成するとすべて正常に動作しますが、デフォルトのコンストラクターを使用すると、メインに戻った後にオブジェクトの状態がおかしくなります。
私のコンストラクター:
HashTable::HashTable()
{
HashTable(53);
}
HashTable::HashTable(int tableSize)
{
currentSize = tableSize;
table.resize(tableSize);
}
オブジェクト作成後のブレークポイントの設定
HashTable ht(size); //this works
HashTable ht; //this does not work
コードをステップ実行すると、オーバーロードされたコンストラクターが正常に呼び出されていることがわかりますが、メインに戻ってテーブルを使用しようとすると (デフォルトのコンストラクターのみを使用する場合)、ベクトルのサイズと変数 currentSize がおかしくなります。
オブジェクトを作成した後、メインに戻る前に:
currentSize = 53
table [size] = 53, [capacity] = 53, empty linked lists fill the vector
電話をかけるとき ht.hash(value)
main では、オブジェクトには次のものがあります。
currentSize = -858993460
table [size] = 0, [capacity] = 0, linked lists obviously gone.
ベクトル自体が 0 にリセットされ、プライベート int currentSize がおかしくなる原因は何ですか。特にコード パスが両方とも機能するためです。 HashTable(int tableSize)
?
解決
@dyp 正しい方向を教えてくれました。
HashTable(53);
一時的なローカル オブジェクトを作成していました。メインのオブジェクトを希望のサイズの 53 に設定していませんでした。
一時オブジェクトを作成するのではなく、メインのオブジェクトでオーバーロードされたコンストラクターを呼び出すには、 this->HashTable::HashTable(53);
(Visual Studio で) オーバーロードされたコンストラクターを呼び出し元のオブジェクトで強制的に呼び出すように機能しました。
編集:gcc コンパイラーはこれを禁止しており、コンパイラーが許可するかどうかに関係なく、これは一般的に悪い習慣であると考えられています。
初期化子リストとして HashTable::HashTable() : HashTable(53) {}
これは、私がやろうとしていたことを達成するための正しい方法であると考えられています。