我目前正在使用c ++中的自定义分配器。这个分配器必须通过移动内存和对象来定期对其内存进行碎片整理。这些移位始终是向下的,这意味着移动的内存块的地址在移动时总是会减少。当旧内存块和新内存块不重叠时,这样做没有问题。如果它们重叠,我首先必须将对象移动到分配器内存之外的临时区域,然后将其移回新的内存块。
如果移动类型的std :: is_trivially_move_constructible为真,那么如果定义了默认移动构造函数中的赋值顺序,我可能会将此额外移动保存到临时内存块。这导致了我的问题:分配的顺序是否定义明确,还是特定于平台?
答案 0 :(得分:2)
来自标准(第15.8.1节[class.copy.ctor])
(14)非联合类X的隐式定义的复制/移动构造函数 执行其基础和成员的成员复制/移动。 [ 注意: 忽略非静态数据成员的默认成员初始值设定项。 另请参见15.6.2中的示例。 - 尾注]顺序 初始化与base的初始化顺序相同 用户定义的构造函数中的成员(见15.6.2)
按照链接引导我们 第15.6.2节[class.base.init]
(13.3)然后,按照它们的顺序初始化非静态数据成员 在类定义中声明(再次无论顺序如何) mem-initializer s)
并没有完全回答这个问题,但正如Igor Tandetnik在他的回答中所说,将一个简单的构造函数转换为std::memmove
答案 1 :(得分:0)
[basic.types] / 3 对于任何简单的可复制类型
T
,如果指向T
的两个指针指向不同的T
个对象{{1} }和obj1
,如果组成obj2
的基础字节(1.7)被复制到obj1
,则obj2
和obj1
都不是基类子对象,obj2
随后应保持与obj2
相同的值。
因此,对于一个简单的可复制类型,简单地复制字节是安全的,例如与obj1
。您可以使用memmove
来测试此特征。
请注意,平凡移动可构造是一个必要但不充分的条件,可以轻易复制:
[class] / 6 平易可复制的课程是一个课程:
(6.1) - 其中每个复制构造函数,移动构造函数,复制赋值运算符和移动赋值运算符(12.8,13.5.3)被删除或无关紧要,
(6.2) - 至少有一个未删除的复制构造函数,移动构造函数,复制赋值运算符或移动赋值运算符,以及
(6.3) - 有一个简单的,未删除的析构函数(12.4)。