我想知道写时复制有什么优点?当然,我并不期望个人观点,而是希望在实际操作中以切实可行的方式在技术上和实践中受益。实际上,我的意思不只是节省&
字符输入。
要澄清的是,此问题是在数据类型的上下文中进行的,在赋值或副本构造中创建一个隐式浅表副本,但对其进行修改会创建一个隐式深表副本,并将更改应用于它而不是原始对象。
我问的原因是,我似乎没有发现将COW作为默认隐式行为的任何优点。我使用Qt,它为许多数据类型实现了COW,实际上所有数据类型都具有一些动态分配的底层存储。但是它如何真正使用户受益呢?
一个例子:
QString s("some text");
QString s1 = s; // now both s and s1 internally use the same resource
qDebug() << s1; // const operation, nothing changes
s1[o] = z; // s1 "detaches" from s, allocates new storage and modifies first character
// s is still "some text"
在此示例中,使用COW可以赢得什么?
如果我们打算做的只是使用const操作,那s1
是多余的,不妨使用s
。
如果我们打算更改该值,则COW仅将资源复制延迟到第一个非常量操作为止,其代价是(为最小)增加隐式共享的引用计数并从共享存储中分离。看起来COW涉及的所有开销都是毫无意义的。
在参数传递的上下文中没有太大区别-如果您不打算修改值,则以const引用的形式传递,如果您要修改,则可以隐式深层复制(如果您不想修改)原始对象,如果要对其进行修改,则通过引用传递。同样,COW似乎是不必要的开销,什么也做不了,仅增加了一个限制,即即使您愿意也不能修改原始值,因为任何更改都将脱离原始对象。
因此,取决于您是否了解COW或遗忘了COW,它可能导致意图含糊的代码和不必要的开销,或者导致完全混乱的行为,与预期不符,使您抓狂。
在我看来,无论您是想要避免不必要的深复制还是打算制作一个深复制,似乎都有更有效,更易读的解决方案。那么,COW的实际好处在哪里呢?我认为必须有一些好处,因为它在如此流行而强大的框架中使用。
此外,据我了解,C ++标准库中现已明确禁止使用COW。不知道我看到的缺点是否与它有关,但是无论哪种方式,都一定有原因。
[]
运算符,在多个线程中对同一字符串进行突变似乎都是很糟糕的设计。因此,COW启用了错误的设计-听起来似乎没有多大好处:)上一段中的观点似乎是正确的,但我本人并不是隐式行为的忠实拥护者-人们倾向于将其视为理所当然,然后很难弄清楚为什么代码无法按预期工作,并一直想知道直到他们找出来检查隐式行为背后隐藏的内容。