3.6 对象操作
当处理复杂的数据结构和对象时,编程中的很多最基本的操作会变得越来越复杂。例如,当你想复制或比较原始数据类型时,过程非常简单。然而复制和比较对象则并不简单。Effective C++中,Scott Meyers专门花了整个小节来讲述复制和分配对象。
类和引用
复杂的数据结构和对象的问题在于它们可能会包含引用。简单对引用的复制不能复制它引用的数据结构或对象。同样,当比较对象时,简单地比较两个指针只是比较了引用,而并未比较指针所指的对象。
当对对象进行比较和复制时你就会意识到该问题。具体来说,问题归结于你是否使用了指针。不管怎样,总有一种方式能复制对象。不过这种方式看上去简单,但实际并不简单。因为对象可以包含引用,必须对整个引用树做有效的复制(如果你确实需要一份深拷贝)。
深拷贝与浅拷贝
追踪所有的引用,并对所有引用对象都创建拷贝,这种方式被称为深拷贝。深拷贝会拥有很多层级。一个对象引用了很多对象,而这些被引用的对象也可能引用其他对象。拷贝本身开销巨大。浅拷贝只会简单地拷贝引用,而不会深入层级。在Object-Oriented Design in Java一书中“Prefer a Tree to a Forest”一节中,Gilbert和McCarty对深拷贝和浅拷贝进行了精彩的讨论。
如图3.8所示,如果只是简单地拷贝对象(称为逐位复制),只会拷贝引用,而不会拷贝实际的对象。因此,两个对象(原始对象和副本)会引用(指向)同一个对象。为了完全复制(需要复制每个引用对象),你必须编写代码来创建所有的子对象。
图3.8 深入对象引用
当比较对象时也有类似的问题。正如拷贝功能一样,比较功能并不像看起来那么简单。因为对象包含引用,必须根据引用树进行有效的对象比较。大多数情况下,语言提供了一种默认的机制来比较对象。当设计类时,你应当在类中提供一个比较功能,从而保证类的行为是符合预期的。 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access