用memcpy移动构造函数

Uld*_*isK 0 c++ move-constructor c++11

我有一个结构,我想要不可复制,只能移动,但因为它包含大量的POD,写移动构造函数会很长,忘记变量将很难调试.例:

struct myStruct{
    int a,b,c,d;
    double e,f,g,h;
    std::complex<double> value1,value2;

    std::unique_ptr<Calculator> calc;

    myStruct(){}
    myStruct(const myStruct &)=delete;
    myStruct(myStruct && other);
};
Run Code Online (Sandbox Code Playgroud)

这种移动构造函数会出现什么问题:

myStruct::myStruct(myStruct && other){
    std::memcpy(this,&other,sizeof(myStruct));
    other.calc.release();
    calc->rebind(this);
}
Run Code Online (Sandbox Code Playgroud)

我可以面对什么问题,这是明确定义的吗?

Use*_*ess 5

最小的改变只是将简单初始化的成员组合在一起,因此您可以memcpy轻松地将它们组合在一起:

struct myStruct{
    struct {
        int a,b,c,d;
        double e,f,g,h;
        std::complex<double> value1,value2;
    } pod;

    std::unique_ptr<Calculator> calc;

    myStruct(){}
    myStruct(const myStruct &)=delete;
    myStruct(myStruct && other);
};

myStruct::myStruct(myStruct && other){
    std::memcpy(&pod,&other.pod,sizeof(pod));
    other.calc.release();
    calc->rebind(this);
}
Run Code Online (Sandbox Code Playgroud)

注意std::complex文字类型,放入pod成员应该是安全的.如果添加类类型的任何其他成员对象,则必须验证自己对memcpy是否安全.


正如Jonathan Wakely所指出的那样,更好的实施方式将回避对pod和非pod(或文字和普通初始化)成员的关注.而是根据您是否要复制或移动它们来分组成员:

struct myStruct{
    struct {
        int a,b,c,d;
        double e,f,g,h;
        std::complex<double> value1,value2;
    } val;

    std::unique_ptr<Calculator> calc;

    myStruct(){}
    myStruct(const myStruct &)=delete;
    myStruct(myStruct && other);
};

myStruct::myStruct(myStruct && other)
  : val(other.val)              // copy the value types
  , calc(std::move(other.calc)) // and move the reference types
{
    calc->rebind(this);
}
Run Code Online (Sandbox Code Playgroud)