c – 如何正确定义移动构造函数?
发布时间:2020-12-16 05:55:51 所属栏目:百科 来源:网络整理
导读:我搜索了互联网,发现了3种定义移动构造函数的方法: 依赖编译器: T(T other) = default; 取消引用这个指针: T(T other) { *this = std::move(other);} 明确地重新分配所有成员: T(T other) { T.a = other.a; T.b = other.b; //...} 哪一个是正确的方法?
我搜索了互联网,发现了3种定义移动构造函数的方法:
>依赖编译器: T(T&& other) = default; >取消引用这个指针: T(T&& other) { *this = std::move(other); } >明确地重新分配所有成员: T(T&& other) { T.a = other.a; T.b = other.b; //... } 哪一个是正确的方法? (还有第二个甚至是正确的?) 解决方法
正确的通用方式是移动构建每个成员,但是这样做是反向版本的反正:
T(T && rhs) : a(std::move(rhs.a)),b(std::move(rhs.b)) { } 作为一个粗略的规则,如果这是所有你需要的,你应该使用默认定义,如果你正在做一些显式实现移动语义的事情,你应该写一个显式的移动构造函数,比如唯一所有权资源管理器: URM(URM && rhs) : resource(rhs.resource) { rhs.resource = nullptr; } 这是否适合的指标可能是您的类是否具有用户定义的析构函数.在该示例中,析构函数将释放受管资源,并且必须仅发生一次,因此必须修改move-from对象. 这是无关紧要的,但是由于你提到了赋值运算符,所以这里是流行的交换和分配/交换成语: void swap(URM & rhs) noexcept // assume members are noexcept-swappable! { using std::swap; swap(resource,rhs.resource); // ... } URM & operator=(URM rhs) noexcept // pass by value { rhs.swap(*this); return *this; } 这种方法的优点是,您只需要一个适用于临时和非临时人员的分配运算符的单一版本,在适当时使用移动构建,只要所有成员都精心设计,您也只需要一个单次交换功能.除此之外,如果交换函数没有被抛出(一个精心设计的类应该允许的话),那么你的赋值运算符就不会抛出,因为所有可能的异常都会在调用站点发生. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |