1

このようなものの使用と説明は何ですか?:

int capacity;
int** number;
this->number = new int*[this->capacity];

私は試験のために勉強していますが、テスト試験では、ポインタからポインタへのオブジェクトを使用し、そこから動的配列を作成する必要があります。2 つのクラスがあります。ウォレット&ウォレットキーパー。ソリューションでは、WalletKeeper のヘッダー ファイルでこれを行いました。

private:
    Wallet** wallets;
    int capacity;
    int size;
    /*other stuff below this*/

そしてコンストラクターで:

WalletKeeper::WalletKeeper(int capacity)
{
    this->capacity = capacity;
    this->size = 0;
    this->wallets = new Wallet*[this->capacity];
    this->initiate();
}

次のような基本的な動的配列を理解しています。

Wallet * wallets = new Wallet[capacity];

これは、このウォレットの配列が作成されるメモリ内の場所を指すポインタを作成することを意味するため、これらのメモリ スロットの内容を変更できます。しかし、なぜポインターの配列へのポインターを作成するのでしょうか? 使用は何ですか?

ウォレットには独自の配列はありません。これを読んだので、別の方法で理解できたはずです:多次元配列への動的ポインターを初期化する正しい方法?

教授は、さらに苦労するまで休暇中です。

4

3 に答える 3

3

ポインターの配列には多くの用途があります。

  1. 並べ替え。配列内のオブジェクトを並べ替えたいとします。ポインターを処理する方が、オブジェクト全体を移動するよりもはるかに高速です。
  2. 動的割り当て。各オブジェクトを個別に削除または割り当てることができます。
  3. 再割り当てとパフォーマンス。配列のサイズを増やしたいとします。実際のオブジェクトを再割り当てすると、さまざまな種類の問題 (無効化) が発生する可能性があります。ただし、ポインターの配列の再割り当ては、多かれ少なかれ問題がなく、はるかに高速です。
于 2016-08-16T15:01:23.800 に答える
1

基本的な考え方は、「配列の配列」を作成できるようにすることです。異なるサイズのサブ配列を持つことができるという点で、マトリックスよりも狭い利点がありますが、すべてのオブジェクトのメモリが配列全体で連続しなくなるという欠点があります。

Wallet ** w_ptr_ptr = new Wallet*[capacity];
for(int i = 0; i < capacity; i++) {
    w_ptr_ptr[i] = new Wallet[i+1];
}

for(int i = 0; i < capacity; i++) {
    for(int j = 0; j < i+1; j++) {
        w_ptr_ptr[i][j] = Wallet(/*...*/);
    }
}

そのコードでw_ptr_ptr[0]は、 とは異なるサイズの配列があることに注意してくださいw_ptr_ptr[1]

私のコメントでほのめかしたように、あなたの教授はこのように教えるべきではありません. このコードは手動でメモリをクリーンアップする必要があり、自動境界チェックを行う能力がないため、次のコードを使用する必要があります。

std::vector<std::vector<Wallet>> wallets;

for(int i = 0; i < capacity; i++) {
    wallets.emplace_back(i+1); //Will automatically create a i+1-sized array.
}

for(int i = 0; i < wallets.size(); i++) { //Note I'm able to query the size here!
    for(int j = 0; j < wallets[i].size(); j++) { //Again I can query the size!
        wallets[i][j] = Wallet(/*...*/);
    }
}
于 2016-08-16T15:05:48.430 に答える