0

这是一个假代码示例

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 作为对新元素的引用,

fred = gFred[z];

实际发生的是 gFred[1] 正在覆盖 gFred[0]。

我在想在这里做的正确的事情,就是把自己的头顶几次,然后把它变成一个指针实现,然后继续我的生活。

我是否正确诊断了这一点?还是我需要更多的教育?

4

5 回答 5

6

是的,你在那里得到了一个结构副本。引用不能被反弹,即它们一旦被初始化就保持不变。

你的解决方案也是合适的。不知道怎么打自己的头。

于 2009-02-26T19:36:40.630 回答
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]
于 2009-02-26T19:44:04.530 回答
1

使用您发布的代码(并假设 Fred 类型是 POD),gFred[0] 正在被覆盖,最终将包含 gFred[z] 中最后一个 z 的 wahatever 副本。

您可以切换到使用指针实现,或者您可以更紧密地确定引用范围:

{    
    size_t z = 0;
    do
    {
        Fred &fred = gFred[z];
        // do odd processing with fred
        z++;
    }
    while (fred.lastElementInSet == 0);
}
于 2009-02-26T19:48:55.343 回答
0

在您提供的代码中,fred始终引用gFred[0]. 如果您希望fred引用随着循环的每次迭代而改变,请删除该行Fred &fred=gFred[0];。然后替换fred = gFred[z];Fred &fred = gFred[z]. 这样,fred每次循环执行时都重新初始化引用。

于 2009-02-26T19:44:28.240 回答
0

编译的机制由 dirkgently 的答案解释,而基本解释是 MSN 的解释(“引用不能被反弹”)。

也许这样读起来更容易:

如果

ptr = &xxx;

表示 的内容ptr是 的地址xxx,则

&fred = gFred[0];

表示 的地址设置fred为指向gFred[0]。IOW,fred现在是gFred[0]. 这就是为什么做fred = xxx覆盖gFred[0]

于 2009-02-26T19:52:42.760 回答