2012-04-30 7 views
0

私のクラスのヘッダファイルの整数配列へのポインタを宣言したいと思います。私は、コンストラクタ整数配列へのポインタの宣言C++

theName = new int[10]; 

この作品は意志で

private: 
int *theName; 

、その後持っていますか?これを行う別の方法がありますので、配列へのポインタがありますか?

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

はまた、デストラクタで、私はそれがtheName整数配列オブジェクトを削除してメモリにnullにtheNameを指します

delete theName; theName = NULL; 

を呼び出すことができますか?

おかげ

+1

本当に良い理由がない限り、たぶん 'std :: vector'を使うべきでしょう。 –

+0

このような小さな配列でヒープ割り当てを行うことはできません。 – chikuba

答えて

5

つの事:

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

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

  • 第3に、リソースを管理するクラスを書くときは、コピーコンストラクタ、コンストラクタの移動、代入演算子のコピー、代入演算子の移動が必要です。

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

+5

これは嫌いですが、これは整数へのポインタと整数配列へのポインタの間に違いはありません "*は真ではありません。 *私はあなたが何を意味しているのか知っていますが、OPはおそらくそうではありません。 –

+0

ありがとうございます!これは本当に助けになり、本当にクリアです! – JDN

+0

@BenjaminLindleyそれは非常に詳細で初心者に混乱しているので、答えの残りの部分を取り除く巨大で気を散らす何かを書くことなくそれに入ることは難しいです。しかし、ええ、それは正確ではありません。 –

1

はい、動作します。

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

theNameをnullに設定すると、オブジェクト全体(したがって、theName)がすぐに存在しなくなるため、デストラクタで余分ですが、良い形式です。

より良いC++アプローチは、std::vector<int>を使用することです。

0

はい、ポインタを初期化する方法です。あなたはしかし、いくつかの問題を抱えている:

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

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

  3. 用語nitpick:

は、そのメモリにtheName整数配列オブジェクトとNULLに次にポイントtheNameを削除しますか?

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

0

これを行う別の方法がありますので、配列へのポインタがありますか?

std::vectorを使用できます。この[大部分]を押して、配列を使用し、次のような利点を提供しているwhereeverのスロットすることができます

  1. それは
  2. に必要がある場合に
  3. メモリ管理について心配する必要は自動的にサイズを変更していないし続けることができます array[index]構文
  4. .at()メソッドで境界チェックを実行できます。

あなたが使用できる最初の要素へのポインタ(CスタイルのAPIなどを与えるために)したい場合:[]削除し、ベクトルとスタッフとの

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

SomeCFunction(&vec[0]); 
0

をはい、非常に素晴らしい答え、これを覚えておいてください:int * pは "int to pointer"型です。それは実際には単一の整数へのポインタです。しかし、このp [5]のように逆参照すると、これは*(p + 5)と同じです。配列アクセスの仕組みもそうです。 (なぜ、配列を最初の要素へのポインタに暗黙的に変換できますか?)しかし、配列型へのポインタがあります。 int(* p)[10]は「サイズ10のintの配列へのポインタ」です。しかし、これはあなたが望むものではありません。もしあなたが今p [5]と言うならば、p + sizeof * p * 5のアドレスにアクセスする*(p + 5)を意味するでしょう。しかしsizeof * pはsizeof int [10]です。 (pはint [10]へのポインタなので、p [5]の型はint [10]になります);-)

3

私はこれを投稿することを躊躇しますが、問題を引き起こしません。

脚本:他の回答のほとんどは間違っています:あなたが作成したものはではなく、の配列へのポインタです。これは、配列の最初の要素を参照するintへのポインタです。

私はあなたの質問に間違った言葉遣いを使用したことのほとんどの問題であるという簡単な理由でそれを投稿するのをためらっています - intへのポインタはほぼ確実にあなたが望んだと思ったものです。本当に得た。

しかし、配列へのポインタとしてのものがあります。ポインタの数学(添え字付きを含む)を行う場合、配列へのポインタは、指している配列のサイズを増やして動作するため、めったに役に立ちません。あなたの場合、10 intを割り当てます。配列内のintを参照するには、ポインタからサブスクリプトを使用することができます。したがって、theName[0]は、最初のinttheName[1]から2番目のintなどを指します。

(たとえば)配列の配列を操作していて、一度にその行全体を移動するポインタを必要とする場合は、配列へのポインタを実際に使用できるようにする必要があります。そのため、ptr[0]が最初の行、ptr[1]の2番目の行などとなりました。例えば: - (定義により)sizeof(char) == 1ので、に少し簡単です

#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; 
} 

私は数学が少しより明らかにするために(代わりにintの)charの配列の配列で動作するようにこれを変更しました数学を解く私は私のマシン上でこのコードを実行すると、私が手アドレスは以下のとおりです。あなたが見ることができるように

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

は、ptr[0]は、全体として、配列のいずれかの方法のアドレスを保持しています。しかし、charへのポインタでは、ptr[1]は1つ大きいアドレスを保持します。しかし、配列へのポインタは、アドレス0x40-0x2C = 0x14 = 20 greaterを保持します。これは、配列(20)に与えたXの次元に適合します。言い換えれば、実際には配列へのポインタを持っており、このポインタ上のポインタの算術演算(または同様に、添え字付き)は、一度に配列全体に関して実行されます。

私は繰り返しますは、しかし:私たちはあなたがほぼ確実代わりstd::vectorを使用しなければならないという事実を無視するならば、少なくとも、あなたが得たあなたが望んでいたタイプとタイプが両方pointer to intました。 pointer to arrayのようなタイプですが、ほぼ確実にではありません。本当に欲しいですか。