这是假代码示例
vector<Fred> gFred;
{
// init gFred
Fred &fred = gFred[0];
size_t z = 0;
do
{
fred = gFred[z];
// do odd processing with fred
z++;
}
while (fred.lastElementInSet == 0);
}
引起我注意的是gFred [0]被覆盖的事实。 这使我认为,而不是将init作为对新元素的引用,
fred = gFred[z];
实际发生的是gFred [1]覆盖了gFred [0]。
我在想这里做的正确的事情,就是把自己带到头几次,把它变成一个指针实现并继续我的生活。
我是否正确诊断出这一点?还是我需要更多的教育?
答案 0 :(得分:6)
是的,你在那里得到一份结构副本。引用不能反弹,即它们在初始化后保持不变。
您的解决方案也是合适的。尽管如此,邓诺还是打了个招呼。
答案 1 :(得分:3)
查看引用的一种方法是将它们视为隐式取消引用的指针。简单地说,它们是指针,但您可以使用常规变量访问语法来使用它们
Fred &fred = gFred[0];
这将创建对向量gFred的第一个元素的引用。 (顺便说一句,你有什么内容吗?)编译器会做这样的事情:
Fred *pFred = &gFred[0];
现在,当你这样做时:
fred = gFred[z];
编译器实际上会做这样的事情:
*pFred = gFred[z];
翻译为:
gFred[0] = gFred[z];
如果你的N
中有N个要素,那么你vector
次这样做了。
如果您尝试初始化vector
的所有元素,请尝试使用此构造函数:
vector(size_type n, const T& t)
其中,
n = size of vector
t = gFred[0]
答案 2 :(得分:1)
使用您发布的代码(假设Fred类型是POD),gFred [0]正在被覆盖并最终将包含gFred [z]中最后一个z的副本。
您可以切换到使用指针实现,或者您可以更仔细地调整参考范围:
{
size_t z = 0;
do
{
Fred &fred = gFred[z];
// do odd processing with fred
z++;
}
while (fred.lastElementInSet == 0);
}
答案 3 :(得分:0)
在您提供的代码中,fred
始终引用gFred[0]
。如果您希望fred
引用随循环的每次迭代而更改,请删除行Fred &fred=gFred[0];
。然后将fred = gFred[z];
替换为Fred &fred = gFred[z]
。这样,每次循环执行时都会重新初始化fred
引用。
答案 4 :(得分:0)
编译机制由dirkgently的答案解释,而基本的解释是MSN的(“引用不能反弹”)。
也许以这种方式阅读会更容易:
如果
ptr = &xxx;
表示ptr
的内容是xxx
的地址,然后是
&fred = gFred[0];
表示fred
的地址设置为指向gFred[0]
。 IOW,fred
现在是gFred[0]
的别名。这就是为什么要fred = xxx
覆盖gFred[0]