假设我有一个向量:
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?
如果它只设置临时块,我该如何为实际块设置它?
答案 0 :(得分:6)
Block c = myBlocks.at(i);
此处c
是myBlocks
中包含的值的副本。
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;