0

クラスのヘッダーファイルで整数配列へのポインタを宣言したいと思います。私は持っています

private:
 int *theName;

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

theName = new int[10];

これは機能しますか?配列へのポインタを持つようにこれを行う別の方法はありますか?

int * theNameは整数配列ではなく整数へのポインターを作成したと思いましたが、これが整数配列へのポインターを作成する場合、整数だけへのポインターをどのように作成しますか?

デストラクタでも電話できますか

delete theName; theName = NULL;

これにより、theName整数配列オブジェクトが削除され、メモリ内でtheNameがnullを指すようになりますか?

ありがとう

4

6 に答える 6

7

4つのこと:

  • 1つは、そうです。これが、配列へのポインタを作成する方法です。整数へのポインタと整数配列へのポインタに違いがないことに注意してください。整数は1つの要素の配列と考えることができます。が整数へのポインタである場合は引き続き使用できx[0]、が配列へのポインタである場合は引き続き使用でき、これらは同じように機能します。x*xx

  • 次に、delete[] theNameではなく delete theName、を使用する必要があります。どこで使用するnew場合でも、を使用する必要がdeleteあり、どこで使用するnew[]場合でも、を使用する必要がありますdelete[]。また、theName = NULLデストラクタを実行すると、theNameとにかくアクセスできなくなるため、設定する必要はありません。

  • 第三に、リソースを管理するクラスを作成するときは、コピーコンストラクター、ムーブコンストラクター、コピー代入演算子、およびムーブ代入演算子を作成する必要があります。

  • 第4に、これを教訓的な演習として行っているのでない限り、実際にはを使用する必要がありますstd::vector。多くの利点があり、実際の欠点はありません。また、を使用する場合は、他の4つのコンストラクターを作成する必要もありませんvector

于 2012-04-30T03:01:02.017 に答える
6

投稿するのは躊躇しますが、問題ないことを願っています。

衒学者になるために:他の答えのほとんどは間違っています:あなたが作成したものは配列へのポインタではありません。intこれは、配列の最初の要素を参照するへのポインタです。

これはほぼ間違いなくあなたの質問で間違った言い回しを使用しただけの問題であるという単純な理由でそれについて投稿することを躊躇します-ポインタintはほぼ間違いなくあなたが望んでいたと思ったものであり、それはあなたが本当に得たものです。

ただし、配列へのポインタなどがあります。ポインタ計算(添え字を含む)を実行すると、配列へのポインタが、それが指している配列のサイズを増分して機能するため、これが役立つことはめったにありません。あなたの場合、10int秒を割り当てます。ポインタから添え字を使用intして配列内のsを参照できるためtheName[0]、最初のinttheName[1]2番目intの、というように参照できます。これは、通常必要なものです。

(たとえば)配列の配列を操作していて、一度にその行全体をウォークスルーするポインターが必要な場合は、配列へのポインターを実際に使用できる可能性がありますptr[0]。最初の行も同様です。ptr[1]2行目など。例えば:

#include <iostream>

static const int x = 20;
static const int y = 10;

int main() {
    char data[y][x];

    auto ptr_array = &data[0];
    char *ptr_char = &data[0][0];

    std::cout << "Address of entire array: " << (void *)data << "\n";

    std::cout << "char *[0] = " << (void *)ptr_char << "\n";
    std::cout << "char *[1] = " << (void *)(ptr_char+1) << "\n";

    std::cout << "array *[0] = " << (void *)ptr_array << "\n";
    std::cout << "array *[1] = " << (void *)(ptr_array+1) << "\n";
    return 0;
}

私はこれをchar(の代わりにint)の配列の配列で動作するように変更して、数学をもう少しわかりやすくしました- sizeof(char) == 1(定義上)数学を理解するのが少し簡単になりました。自分のマシンでこのコードを実行すると、取得するアドレスは次のとおりです。

Address of entire array: 0047FD2C
char *[0] = 0047FD2C
char *[1] = 0047FD2D
array *[0] = 0047FD2C
array *[1] = 0047FD40

ご覧のとおり、ptr[0]いずれかの方法で配列全体のアドレスを保持します。ただし、へのポインタを使用するとcharptr[1]1つ大きいアドレスを保持します。ただし、配列へのポインタは、アドレス0x40-0x2C = 0x14 = 20より大きいアドレスを保持します。これは、配列に指定したX次元(20)に適合します。言い換えると、実際には配列へのポインターがあり、このポインターに対するポインター演算(または同等に添え字)は、一度に配列全体に関して機能します。

ただし、繰り返します。少なくとも、代わりに使用する必要があるという事実を無視すると、必要なstd::vectorタイプと取得したタイプの両方が使用されpointer to intます。のようなタイプがありますが、それはあなたが本当に望んでいpointer to arrayたことをほぼ確実に望んでいません。

于 2012-04-30T03:41:36.557 に答える
1

はい、うまくいきます。

書く必要がありますdelete[] theName-で割り当てた場合new TYPE[]は、演算子で削除する必要がありますdelete[]

オブジェクト全体(したがって)がすぐに存在しなくなるtheNameため、デストラクタでは不要ですが、nullに設定することは適切な形式です。theName

より良いC++アプローチは、を使用することかもしれませんstd::vector<int>

于 2012-04-30T03:01:59.983 に答える
0

はい、delete []やvectorなどで非常に良い答えが得られますが、これを覚えておいてください。int*pの型は「pointertoint」です。それは確かに単一の整数へのポインタです。ただし、このp [5]のように逆参照する場合、これは*(p + 5)と言うのと同じです。これは、アレイアクセスの仕組みでもあります。(そして、配列を最初の要素へのポインターに暗黙的に変換できる理由。)ただし、配列型へのポインターがあります。int(* p)[10]は、「サイズ10のintの配列へのポインター」です。しかし、これはあなたが望むものではありません。ここでp[5]と言うと、アドレスp + sizeof * p * 5にアクセスする*(p + 5)を意味するためです。ただし、sizeof*pはsizeofint[10]であるため、混乱が生じます。(そしてもちろん、pはint [10]へのポインタなので、p[5]のタイプはint[10]になります);-)

于 2012-04-30T03:15:42.840 に答える
0

はい、それがポインタを初期化する方法です。ただし、いくつかの問題があります。

  1. delete []で割り当てるものはすべて呼び出す必要がありますnew[]。コードが意図したとおりに機能せず、結果としてUBになります。

  2. コピーコンストラクタと代入演算子を実装する必要があります。そのポインタがあなたのタイプの別のインスタンスにコピーされるとどうなりますか?あなたはdelete []それを二度呼ぶことになります。

  3. 用語の落とし穴:

それはName整数配列オブジェクトを削除してからメモリ内のnullを指しますか?theName

いいえ、に設定theNameされNULLます。 theName値を持つ他の変数と同じようにです。NULLこの変数はたまたまアドレスであるため、そのように使用すると、はい、その値は、それが何であれ、の数値になります。

于 2012-04-30T03:02:04.567 に答える
0

配列へのポインタを持つようにこれを行う別の方法はありますか?

を使用できますstd::vector。これは[ほとんどの場合]アレイを使用している場所ならどこにでも挿入でき、次の利点があります。

  1. メモリ管理について心配する必要はありません
  2. 必要に応じて自動的にサイズ変更
  3. array[index]構文を引き続き使用できます
  4. メソッドを使用して境界チェックを実行できます.at()

最初の要素へのポインターが必要な場合(CスタイルのAPIなどに提供するため)、次を使用できます。

std::vector<int> vec(10);

SomeCFunction(&vec[0]);
于 2012-04-30T03:02:56.743 に答える