3

我是 C++ 新手,所以这可能是一个简单的问题。我在类预测器中声明了一个向量向量:

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]);

这给了我两个不同的地址,我希望得到相同的地址。我犯了什么愚蠢的错误?

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

这是两个不同的对象。&bit_counter是局部变量的地址,其中&data[i][j]是内部对象的地址Vector

BitCounter bit_counter = data[i][j];意思是“使用”的值构造一个新BitCounter对象data[i][j]new BitCounter(data[i][j])this 和(这有点类似于 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 回答