我是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]);
这给了我两个不同的地址,我希望得到相同的地址。我做了什么骨头错误?
答案 0 :(得分: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";
答案 1 :(得分: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
语句成为obvoius:
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的赋值(如果它不是常量)将更改引用的对象本身。