就地构造(placement new)与移动构造(std::move)
1.就地构造通常与 union 关键字一并使用,因为union会进行延迟构造并且预先开辟空的内存空间,因此这样的组合任务是较佳实现。
例子:
class FixedValueMessage { /* 定值数据 */ public: explicit FixedValueMessage(const EthernetDataFrame ðernetDataFrame) : ethernetDataFrame({ethernetDataFrame}) { if (ethernetDataFrame.getAPPIDType() != APPIDType::Type::fixedValue_send) { throw std::runtime_error( "Constructor illegally, EthernetDataFrame type is " + ethernetDataFrame.getAPPIDTypeString() + "."); } auto data = ethernetDataFrame.getAPDU(); if (data.empty()) { throw std::runtime_error("Constructor illegally, EthernetDataFrame data is empty."); } /* 分别构造8个通道的 零漂值 和 线性值 */ ptrdiff_t offset = 0l; new(&channel1) Channel{data.cbegin(), data.cbegin() + Channel::getSizeInBytes()}; offset += Channel::getSizeInBytes(); new(&channel2) Channel{data.cbegin() + offset, data.cbegin() + offset + Channel::getSizeInBytes()}; offset += Channel::getSizeInBytes(); new(&channel3) Channel{data.cbegin() + offset, data.cbegin() + offset + Channel::getSizeInBytes()}; offset += Channel::getSizeInBytes(); new(&channel4) Channel{data.cbegin() + offset, data.cbegin() + offset + Channel::getSizeInBytes()}; offset += Channel::getSizeInBytes(); new(&channel5) Channel{data.cbegin() + offset, data.cbegin() + offset + Channel::getSizeInBytes()}; offset += Channel::getSizeInBytes(); new(&channel6) Channel{data.cbegin() + offset, data.cbegin() + offset + Channel::getSizeInBytes()}; offset += Channel::getSizeInBytes(); new(&channel7) Channel{data.cbegin() + offset, data.cbegin() + offset + Channel::getSizeInBytes()}; offset += Channel::getSizeInBytes(); new(&channel8) Channel{data.cbegin() + offset, data.cbegin() + offset + Channel::getSizeInBytes()}; offset += Channel::getSizeInBytes(); /* 拷贝采样频率 */ std::copy(data.cbegin() + offset, data.cbegin() + offset + ARR_SIZE(samplingFrequency), samplingFrequency); } ~FixedValueMessage() = default; friend class EthernetDataFrame; private: union { Channel channel1; /* 通道1 */ }; uint8_t samplingFrequency[2]{}; /* 采样频率 */ EthernetDataFrame ethernetDataFrame; /* 原始帧 */ };
2. std::move通常应当在尚未申请空间时使用,本质是一种资源所有权的转移,从而避免申请空间的昂贵开销。

浙公网安备 33010602011771号