在矢量/列表中,您实际将它应用于对象吗? (C ++)

时间:2011-04-26 06:10:49

标签: c++ vector

假设我有一个向量:

vector<Block> myBlocks;

让我说我这样做:

Block b(10); //Let's assume this will set b's variable: x to 10
myBlocks.push_back(b); //Add it to the vector/list

现在,如果我在其他地方做了这件事怎么办:

for(int i = 0; i<myBlocks.size(); i++){
    Block c = myBlocks.at(i);
    c.x = 15; //Will this work?
}

我放置的地方:c.x = 15;,是否实际上将该块的x位置设置为15? 或者只是将临时块的x位置设置为15? 如果它只设置临时块,我该如何为实际块设置它?

5 个答案:

答案 0 :(得分:6)

Block c = myBlocks.at(i);

此处cmyBlocks中包含的值的副本

Block& c = myBlocks.at(i);

此处c引用(即别名myBlocks中包含的值。

我怀疑你想要后者。

答案 1 :(得分:2)

  

我放的地方:“c.x = 15”,是否实际上将该块的x位置设置为15?

没有

  

或者只是将临时块的x位置设置为15?

  

如果仅设置临时块,如何为实际块设置它?

myBlocks.at(i).x = 15 ; // Assuming x has a public access.

Block c = myBlocks.at(i);

myBlocks.at(i)返回复制到c的对象。因此,对象(向量中的对象,c)是具有自己成员的两个不同对象(假设类没有原始指针)。

答案 2 :(得分:1)

这将有效:

  Block& c = myBlocks.at(i); // note reference here
  c.x = 15; //Will this work?

你们也会工作但最后什么都不做。

答案 3 :(得分:1)

您正在处理原始元素的副本。

我建议您更喜欢使用惯用语iterator

for(std:vector<Block>::iterator it=myBlocks.begin(); it!=myBlocks.end(); it++)
{
    it->x = 15 ;// this will work - will update the actual element, not its copy!
    (*it).x = 15 ;// this will also work
}

答案 4 :(得分:1)

C ++是一种基于复制语义的语言,所以当您执行类似

的操作时
Block c = myblocks.at(i);

你确实在制作一个块对象的副本。请注意,这在C ++语言中并不称为“临时”... C ++中的临时表是一个非常具体的术语,意思是自动创建并且未声明的未命名对象。

此复制行为与许多其他语言(如Python或Java)完全不同,而引用语义的方法相反。

您可以要求不使用“参考”明确地制作副本......

Block& c = myblocks.at(i);

在这种情况下,当你修改c时,你正在使用向量中的原始元素。请注意,在这种情况下,您必须注意保留引用的时间长度,因为例如,如果向向量添加元素,则所有现有引用和迭代器可能因向量重新分配而无效,并且使用它们将召唤可怕的未定义行为守护进程。

如果引用或迭代器无效,取决于容器的类型,对容器上的操作类型以及空间预留等事实,所以我的建议是阅读一本好的C ++书来理解这些部分

另请注意,std::vector::operator []std::vector::at实际上都会返回引用,因此您的代码也可以使用更多succint和惯用语法更改向量中的原始对象

myblocks.at(i).x = 15;