0

Javaから、私はこれを行うことができることに慣れています:

public class SomeClass {
    public int field1;
}

SomeClass[] data = new SomeClass[10];
for (int i = 0; i < 10; i++) {
    data[i] = new SomeClass(); 
    SomeClass d = data[i];
    d.field1 = 10;
}

for (int i = 0; i < 10; i++) {
    SomeClass d = data[i];
    System.out.println("Value of data [" + i + "] is [" + d.field1 + "]");
}

そして、これはうまく動作し、印刷します:

Value of data [0] is [10]
Value of data [1] is [10]
... etc

したがって、Java では、最初にすべての null 値を持つ配列を作成し、最初のループで新しい SomeClass を作成して配列のスロットに割り当てます。これを行わないと、NullPointerException が発生します。

大丈夫だ。

質問: C++ で同じことをしようとしています。失敗例と実用例が 1 つあります。しかし、なぜそれが機能するのかわかりません (または、選択した例によっては機能しません)。誰でも詳しく説明できますか?

まず、失敗したコード:

int main(int argc, char **argv) {
    MyClass data[10];
    for (int y = 0; y < 10; y++) {
        MyClass d = data[y];
        cout << "INITIALLY (garbage): [" << d.field1 << ", " << d.field2 << "] " << endl;
        // assign values
        d.field1 = 2;
        d.field2 = 3;
    }

    // print out data of first 10
    cout << "Printing out data after initialization" << endl;
    for (int y = 0; y < 10; y++) {
        MyClass d = data[y];
        cout << "[" << d.field1 << ", " << d.field2 << "] " << endl;
    }
}

したがって、正しく理解できれば、この StackOverflow の質問に従って、上記のコードのように Struct の配列を作成できます。

私が気づいたのは、使用しない場合:

MyClass d = data[y];
d.field1 = 2;
d.field2 = 3;

しかし、代わりに私は:

data[y].field1 = 2;
data[y].field2 = 3;

それは機能します。

ただし、別の値を使用することを主張する場合でも、次のようにすることで機能させることができます。

MyClass * d = &data[y];
d->field1 = 2;
d->field2 = 3;

出力を印刷する際には何も変更しません。そして、上記の作品。

そのため、data[y] へのポインターを使用する場合、何かが明らかに異なります。ただし、これについて明確な答えは見つかりません。理由を説明できる人はいますか?

この質問が重複している場合は、申し訳ありませんが、「なぜ」の部分で本当の答えを見つけることができませんでした. コード スニペットだけでは十分とは言えません ;)

PPS: この配列をヒープに割り当てていないことは承知しています。その主題に触れて比較するためのボーナスポイント:)

4

3 に答える 3

1

ここでコピーを作成しています:

MyClass d = data[y];

dに影響を与えない変更data[y]

代わりに参照してください:

MyClass& d = data[y];

d要素を参照するようになりましたdata[y]。C++ では、参照はエイリアスのように動作することに注意してください。再割り当てすることはできません。例えば

d = someMyClassInstance;

someMyClassInstanceの値をに代入する効果がありますdata[y]

于 2013-02-26T12:01:49.293 に答える
1

これ:

    MyClass d = data[y];
    d.field1 = 2;
    d.field2 = 3;

dは のコピーになっているため、効果はありませんdata[y]。代わりに言った場合MyClass& dは、(非 const) 参照があり、これを変更してから でそれらの変更を観察できますdata

于 2013-02-26T12:01:59.407 に答える
1

C++ では、オブジェクトはストレージの領域、つまりメモリの領域です。変数は、既存のオブジェクトへのポインターまたは参照として明示的に修飾されていない限り、オブジェクトを直接示します。

あなたが書くとき:

MyClass d = data[y];

typeの変数を宣言、それをスタック上のオブジェクトを示すものとして定義し、 object から初期化しています。とは別のオブジェクトなので、変更しても には影響しません。MyClassdata[y]ddata[y]ddata[y]

あなたが書きたい:

MyClass &d = data[y];
        ^--- here

アンパサンド&はobject への参照をd示すため、オブジェクトが最初に示されたストレージの領域内 (つまり、そのアドレス)data[y]に存在し続ける限り、そのオブジェクトを変更するために使用できます。data[y]d

ポインターの使用も同様ですが、ポインターを再配置して別のオブジェクトを指すことができるため、間接構文 (*または->) を使用してポインターが指すオブジェクトを示す必要があります。

于 2013-02-26T12:07:22.900 に答える