21

C++ では、クラスのポインターに対して ( ->) 矢印演算子を使用して、次のようにそのクラスのメンバーにアクセスすることがわかっています。

#include <iostream>
using namespace std;

class myclass{
    private:
        int a,b;
    public:
        void setdata(int i,int j){
            a=i;
            b=j;
        }
};

int main() {
    myclass *p;
    p = new myclass;
    p->setdata(5,6);
    return 0;
}

次に、の配列を作成しますmyclass

p=new myclass[10];

myclass( ) 矢印演算子を使用してメンバーにアクセスすると->、次のエラーが発生します。

base operand of '->' has non-pointer type 'myclass'

.しかし、( ) 演算子を介してクラス メンバーにアクセスしている間は機能します。これらのことは私を混乱させます。.クラスの配列に( ) 演算子を使用する必要があるのはなぜですか?

4

6 に答える 6

10

ポインター変数 x の場合、

myclass *x;
  • *x「xが指しているオブジェクトを取得する」ことを意味します
  • x->setdata(1, 2)と同じ(*x).setdata(1, 2)です
  • x[n]「配列のn番目のオブジェクトを取得する」ことを意味します。

たとえばx->setdata(1, 2)は と同じx[0].setdata(1, 2)です。

于 2013-07-18T06:55:43.937 に答える
5

[] を p[3] のように使用することで、配列 + インデックス シフトへのポインターを既に逆参照しているためです。p[3] はポインターではなくオブジェクトであるため、その後は "." を使用する必要があります。

于 2013-07-18T06:45:41.040 に答える
4

後...

MyClass* p = new myclass[10];

...p は MyClass オブジェクトの配列へのポインタです。「配列へのポインター」のことは、最初に削除する必要があります。配列へのポインターがある場合は常に、配列内の n 番目の要素への参照p[n]が効果的に提供されるため、実質的に. そのため、メンバー alaにアクセスするには が必要であり、この場合、ポインター固有の表記法が間違っている理由です....MyClass&.MyClassp[n].member->

p->member(for any member) は引き続き有効であり、 と同等p[0].memberであるため、配列の最初の要素にアクセスするためにのみ使用できることに注意してください。「p」が配列へのポインターであることが知られているプログラムのコンテキストにいるときは常に、それが配列であるという事実を隠すため、まったく使用しないことを強くお勧めしますpq場合によっては、単一の配列要素を参照する目的で別のポインターを作成することもできますが、そうである場合[0]とそうでない場合がありますq->member。のような変数qは、配列の反復にも使用できます。しかし、場合によっては、必要になることがあります。そのため、事前delete[] p;に変更する傾向はありません...アドレスやpp[0]delete[] p;p未定義の動作になります (これは実装定義にすることができ、まだ配列内を指している場合はたまたま Windows 上にありますが、移植性はありません)。

于 2013-07-18T06:50:40.983 に答える
1

おそらく、それを考慮することは洞察力に富んでいます。

myclass obj;
auto p = &obj;  // avoid `new` with plain pointers. That combination is
               //  safer replaced by unique_ptr or std::vector.

以下はすべて機能し、同等です。

p->setdata(5, 6);
(*p).setdata(5, 6);
p[0].setdata(5, 6);
0[p].setdata(5, 6);

これ[]は、プレーンな C 配列にオフセットを追加できる追加機能を備えた、実際にはポインター逆参照演算子であることを示しています。

一般に、C++ コードで C 配列を使用することには疑問があります。あなたの例の明らかな代替手段は次のstd::vectorとおりです。

std::vector<myclass> array(10);

ここでは、array[n]以前と同じように使用できますp[n]が、

  • インターフェイスにはポインターがないため、愚かなポインターのアイデアは得られません。
  • 適切な自動メモリ管理が得られます。つまり、配列が範囲外になると、オブジェクトとそのメモリが自動的に削除されます
  • 必要に応じて境界チェックを取得できます ( array.at(n))
  • (C++11) を使用すると、配列全体を簡単にループできますfor(auto& obj: array){...}
于 2013-07-18T06:53:25.780 に答える