1

C++のクラスのプライベートメンバーについて質問があります。

私はこのように定義されたクラスを持っています:

class Hello
{
   private:
      int a[2][2] = {{1,1},{2,2}};
   public:
      int* getA();
} hello;

aは配列であり、クラスhelloのプライベートメンバーであり、クラスの外部からのアクセスから保護されてgetA()いますが、配列のアドレスを返すために使用する場合は、次のようになります。

int* Hello::getA()
{
   return &a[2][2];
}

クラスの外部でhelloは、変数を使用して次のa[2][2]ようなアドレスを保持します。

int* i = getA();

iのアドレスはありますa[2][2]か?arrayこのようにクラスの外側を変更できますか?まだキーワードで保護されていますかa[2][2]private

4

3 に答える 3

10

何が起こるかというと、プライベートメンバーにポインタを返したということです。呼び出し元がそのポインタを取得すると、ポイントされた配列要素を自由に変更できます。保護privateはなく、もはや関連性がありません。

さらに、発信者がそのポインタを使って何をするか、または発信者がそのポインタをどれだけ長く保持するかを制御することはできません。a強制する必要のある不変条件がある場合、それはできません。aが動的に割り当てられ、再割り当てする必要がある場合、それはできません。

これは、ポインタをプライベートメンバーにリークすることがしばしば良い考えではない理由の良いデモンストレーションです。

(ここでは、有効な要素へのポインターを返すことを意図していると思いますa[2][2]。範囲外です。)

値を変更したくない場合、配列の値を読み取りたいだけの場合、それを行うためのより良い方法はありますか?

このような場合、値またはconst参照のいずれかで要素を返します(ポインターで返すこともできますがconst、呼び出し元にとっては不必要に厄介になります)。

于 2012-12-03T20:15:21.443 に答える
0

無効なインデックスにアクセスするため、未定義の動作が発生します。&a[2][2]

それ以外は、privateほとんどがプログラマーのキーワードであり、実行時チェックを強制しません。

于 2012-12-03T20:16:03.213 に答える
0

私の知る限り、2次元配列にはダブルポインタを返す必要があります。

int ** Hello::getA()
{
    &a[0][0];
}

あなたは自由に行うことができます

 myHello.getA()[1][1] = value; //better use pointer just in place than storing it anywhere anyway.

ちなみに、配列は0ベースのインデックスなので、宣言すると

int a[5];

アドレス可能な最大インデックスはa[4]です(1ではなく0から始まる5つのメモリ位置があります。したがって、a [0]、a [1]、a [2]、a [3]、a[4]があります。 )。

とにかく、生のポインタを返すことは、何をしているのかがわかるまではあまり良い習慣ではありません。

returninにも注意してください

return &a[1];// is wrong (if you have a[2])

あなたがするなら

Hello.getA()[1];

実際には、a [2]にアクセスしようとしていますが、a [1]まであるため、a [2]は無効です(a [1]は2番目の値であり、a [1]は次の2番目の値を意味します)。 2番目の値は3番目の値です!)

..運が良ければ、セグメンテーション違反が発生します。運が悪ければ、ある時点で未定義の値を取得する理由を検索してデバッグする必要があります。

于 2012-12-03T20:26:26.350 に答える