关于C ++副本(value1 = value2)

时间:2013-08-25 05:34:36

标签: c++

我在AS3(一个OO Javascript)中编码,我正在学习C ++。

似乎在C ++中如果你instance1 = instance2复制instance1并命名副本instance2。不像AS3,只有“字符串”和数字会像那样重复,而其他类型被“引用”,所以两者都指向同一个对象(如C ++指针)。

所以我的问题是:

假设我有“战地4”(或任何硬件饥饿游戏)的源代码,我正在运行游戏主类的实例,如下所示:BattleField4 gameInstance = new BattleField4()和游戏5分钟后运行代码执行此操作:BattleField4 gameCopy = gameInstance

这是否意味着内存中加载的游戏进度和图形的“完整副本”?

如果游戏将10Gb的内存加载到RAM中,那么gameCopy = gameInstance之后会加载20GB的内存吗?

感谢您的帮助,我希望我的英语很清楚。

6 个答案:

答案 0 :(得分:4)

在C ++中,如果你有obj类型的某个对象Type,那么你执行:

obj = newObj;

newObj也是Type类型的对象,这将调用Type的复制构造函数。会执行“完整副本”吗?

这取决于Type如何实现复制构造函数。请参阅在C ++中,允许类型选择创建副本时会发生什么。有时,它只是复制内部数据。有时,您必须在类型中实例化新对象,以便可以正确复制指针内部保存的较大对象。

有时候,我们说有问题的Type有“参考语义”。这意味着通过“复制”Type个对象,你得到的是两个独立的Type对象,它们在内部引用相同的数据。也就是说,他们都引用相同的东西。这是完全有效的,并且在许多实用程序C ++类中使用。

有时,我们完全禁止完全禁止复制。这通常是针对不适合引用语义的对象完成的,复制它们会过于繁琐。如果游戏中有一个代表游戏的庞大的整体对象,那么它将是不可复制的,或者它的复制构造函数将完全破坏并且不起作用(游戏开发者对这些东西非常懒惰)。

答案 1 :(得分:3)

程序员不这样做。没有一个巨大的类包含绝对的一切,如果有的话,你就不会复制它。你会传递指针或对它的引用。也就是说,如果你确实有一个疯狂的巨大物体,那么你做了

CrazyHuge crazy_huge_object_2 = crazy_huge_object;

你会(可能,取决于复制语义)有两个疯狂的巨大物体,你将花费两倍你原来疯狂的大量内存。

答案 2 :(得分:0)

您的所有示例都没有显示引用的使用。在C ++中,值语义是默认值。可以把它想象成C#或Java中的struct

如果您想要引用语义,请使用指针或引用。

答案 3 :(得分:0)

默认情况下,C ++将按值传递,除非它是一个vanilla数组,它作为指针传递。这与大多数语言不同,只有原语通过值传递,所有用户对象都通过引用自动传递。

话虽如此 - 例如Qt容器并不真正复制实际容器,除非你试图修改它,这被称为“复制或写入”,隐含共享用于阅读。

根据你的情况 - 如果BattleField4类提供了“深层复制”构造函数或赋值运算符,那么这是可能的,但我怀疑任何心智正常的人都会设计一个这样的游戏类并且这样的大小。

游戏层次结构仍然存在,但它不会被限制在单个类实例中,它将成为多态层次结构的一部分。这意味着它将特别适用于层次结构基类中存在并为每个特定对象实现的任何方法的递归树遍历。这样的操作很可能不会发生在RAM内存中,但会将层次结构保存到磁盘 - 这就是保存和加载游戏进度的方式 - 所有游戏对象的整个状态被序列化为磁盘以保存,并反序列化为恢复。当然,相同的技术可以用于你所要求的,但它听起来不是一个聪明的事情。是的,在深拷贝的情况下,它将占用内存的两倍。如果对象可以在不影响另一个的情况下进行更改,则将有两个单独的树。

答案 4 :(得分:0)

C ++中任何复杂类型的赋值都是用户定义的。标量和简单的聚合赋值是按值计算的,但是一旦对象开始获取与同伴和依赖关系的关系,您就会告诉C ++究竟哪些部分需要真正的重复以及复制将具有哪些其他影响。您的游戏的顶级媒体对象库存几乎肯定是一个简单的参考副本。

答案 5 :(得分:0)

我自己回答了我的问题:

复制对象的每个属性都会被复制。是的,这可能是一个性能问题。这就是人们使用指针的原因。 使用“=”运算符时,C ++会对对象进行“浅复制”(默认情况下)。可以定义复制构造函数来更改它,例如创建一个具有“深层复制”模式的类。

搜索什么是“浅拷贝”给了我关于C ++对象拷贝如何工作的信息。

“Shallow Copy”与“Deep Copy”之间的这种比较非常有用:

  

对于包含指向其他对象的指针的对象,浅表副本仅复制指针而不复制它们指向的对象。结果是两个对象指向同一个包含的对象。深层复制复制指针和它们指向的对象,以及该对象中包含的任何指针或对象,依此类推。   如果您只需要浅拷贝,请避免执行深层复制。

相关问题