3

私は C++ を初めて使用するので、これはおそらく簡単な質問です。クラス Predictor で宣言されたベクトルのベクトルがあります。

class Predictor{
    std::vector<std::vector<BitCounter>> data;
public:
    Predictor();
    void addBit(int x);
};

BitCounter は次のように宣言されます。

class BitCounter {
    short int count0 = 0;
    short int count1 = 0;
public:
    BitCounter();
    short int getCount0();
    short int getCount1();
    void addBit(int x);
};

Predictor::addBit には、次の行があります。

BitCounter bit_counter = data[i][j];
printf("%p %p\n", &bit_counter, &data[i][j]);

これにより、同一のアドレスを取得することを期待していた 2 つの異なるアドレスが得られます。私が犯している骨の折れるエラーは何ですか?

4

2 に答える 2

2

これによりBitCounterコピーが作成されます。

BitCounter bit_counter = data[i][j];

ここでbit_counterは、 にあるもののコピーであるdata[i][j]ため、別のアドレスを持っています。

ネストされたベクター内の要素を参照する場合は、代わりに参照を使用できます。

const BitCounter& bit_counter = data[i][j];

ここで、bit_counterは含まれるもののエイリアスであるdata[i][j]ため、アドレス取得演算子は両方に対して同じアドレスを生成します。

const BitCounter& bit_counter = data[i][j];
std::cout << &bit_counter << "\n";
std::cout << &data[i][j] << "\n";
于 2013-05-05T16:33:17.993 に答える
2

これらは 2 つの異なるオブジェクトです。&bit_counterはローカル変数&data[i][j]のアドレスで、 は 内のオブジェクトのアドレスですVector

BitCounter bit_counter = data[i][j];BitCounter「の値を使用して新しいオブジェクトを構築する」ことを意味しますdata[i][j]new BitCounter(data[i][j])これと(Java/C# で発生するものにより似ています)との主な違いは、この場合、オブジェクトの有効期間が変数のスコープ、つまり現在のブロックによって制限されることです。

したがって、Java と同様の (しかし同一ではない) 動作を取得したい場合は、ポインター型を使用する必要があります。これにより、printfステートメントがわかりにくくなります。

BitCounter* bit_counter = &data[i][j];
printf("%p %p\n", bit_counter, &data[i][j]);

ここで提案されているように、参照を使用できます。

const BitCounter& bit_counter = data[i][j];
printf("%p %p\n", &bit_counter, &data[i][j]);

ただし、Java/C# での参照の場合とは異なり、参照は変更できないことに注意してください。そのため、bit_counter への代入 (定数でない場合) は、参照されるオブジェクト自体を変更します。

于 2013-05-05T16:33:38.077 に答える