@@ -292,7 +292,7 @@ Value o(kObjectType);
292
292
Value a(kArrayType);
293
293
~~~~~~~~~~
294
294
295
- ## 转移语意 (Move Semantics) {#MoveSemantics}
295
+ ## 转移语义 (Move Semantics) {#MoveSemantics}
296
296
297
297
在设计 RapidJSON 时有一个非常特别的决定,就是 Value 赋值并不是把来源 Value 复制至目的 Value,而是把把来源 Value 转移(move)至目的 Value。例如:
298
298
@@ -302,13 +302,13 @@ Value b(456);
302
302
b = a; // a 变成 Null,b 变成数字 123。
303
303
~~~~~~~~~~
304
304
305
- 
305
+ 
306
306
307
- 为什么?此语意有何优点 ?
307
+ 为什么?此语义有何优点 ?
308
308
309
309
最简单的答案就是性能。对于固定大小的 JSON 类型(Number、True、False、Null),复制它们是简单快捷。然而,对于可变大小的 JSON 类型(String、Array、Object),复制它们会产生大量开销,而且这些开销常常不被察觉。尤其是当我们需要创建临时 Object,把它复制至另一变量,然后再析构它。
310
310
311
- 例如,若使用正常 * 复制 * 语意 :
311
+ 例如,若使用正常 * 复制 * 语义 :
312
312
313
313
~~~~~~~~~~cpp
314
314
Value o(kObjectType);
@@ -321,15 +321,15 @@ Value o(kObjectType);
321
321
}
322
322
~~~~~~~~~~
323
323
324
- ![ 复制语意产生大量的复制操作 。] ( diagram/move2.png )
324
+ ![ 复制语义产生大量的复制操作 。] ( diagram/move2.png )
325
325
326
326
那个 ` o ` Object 需要分配一个和 contacts 相同大小的缓冲区,对 conacts 做深度复制,并最终要析构 contacts。这样会产生大量无必要的内存分配/释放,以及内存复制。
327
327
328
328
有一些方案可避免实质地复制这些数据,例如引用计数(reference counting)、垃圾回收(garbage collection, GC)。
329
329
330
- 为了使 RapidJSON 简单及快速,我们选择了对赋值采用 * 转移 * 语意 。这方法与 ` std::auto_ptr ` 相似,都是在赋值时转移拥有权。转移快得多简单得多,只需要析构原来的 Value,把来源 ` memcpy() ` 至目标,最后把来源设置为 Null 类型。
330
+ 为了使 RapidJSON 简单及快速,我们选择了对赋值采用 * 转移 * 语义 。这方法与 ` std::auto_ptr ` 相似,都是在赋值时转移拥有权。转移快得多简单得多,只需要析构原来的 Value,把来源 ` memcpy() ` 至目标,最后把来源设置为 Null 类型。
331
331
332
- 因此,使用转移语意后 ,上面的例子变成:
332
+ 因此,使用转移语义后 ,上面的例子变成:
333
333
334
334
~~~~~~~~~~ cpp
335
335
Value o (kObjectType);
@@ -341,11 +341,11 @@ Value o(kObjectType);
341
341
}
342
342
~~~~~~~~~~
343
343
344
- 
344
+ 
345
345
346
- 在 C++11 中这称为转移赋值操作(move assignment operator)。由于 RapidJSON 支持 C++03,它在赋值操作采用转移语意 ,其它修改形函数如 `AddMember()`, `PushBack()` 也采用转移语意 。
346
+ 在 C++11 中这称为转移赋值操作(move assignment operator)。由于 RapidJSON 支持 C++03,它在赋值操作采用转移语义 ,其它修改形函数如 `AddMember()`, `PushBack()` 也采用转移语义 。
347
347
348
- ### 转移语意及临时值 {#TemporaryValues}
348
+ ### 转移语义及临时值 {#TemporaryValues}
349
349
350
350
有时候,我们想直接构造一个 Value 并传递给一个“转移”函数(如 `PushBack()`、`AddMember()`)。由于临时对象是不能转换为正常的 Value 引用,我们加入了一个方便的 `Move()` 函数:
351
351
0 commit comments