能否从自定义移动赋值运算符中调用默认移动赋值运算符?
解决方案:避免手动维护移动赋值运算符
完全可以通过调用默认移动赋值运算符来简化代码,避免后续新增成员时手动修改移动赋值逻辑。不过需要注意正确的实现方式,同时也有更优的替代方案。
方法一:复用默认移动赋值行为
由于你自定义了移动赋值运算符,编译器不会自动生成默认版本,所以需要显式让编译器生成一个默认的移动赋值辅助函数,再在自定义运算符中调用它:
struct Handle { int* ptr_to_something; // 让编译器生成默认移动赋值的辅助函数 Handle& default_move_assign(Handle&& other) = default; // 自定义移动赋值运算符 Handle& operator=(Handle&& other) { // 先调用默认移动赋值,自动处理所有成员(包括后续新增的成员) default_move_assign(std::move(other)); // 执行你的特殊操作:将other的指针置空 other.ptr_to_something = nullptr; return *this; } int member1; int member2; int member3; // 后续新增成员时,无需修改移动赋值运算符,默认逻辑会自动处理 };
注意事项
如果ptr_to_something指向动态分配的内存,你需要在调用默认移动赋值前先释放当前对象的指针,避免内存泄漏:
Handle& operator=(Handle&& other) { // 先释放当前指针(如果需要) delete ptr_to_something; // 再调用默认移动赋值 default_move_assign(std::move(other)); other.ptr_to_something = nullptr; return *this; }
更优方案:使用智能指针管理内存
如果ptr_to_something是用来管理动态内存的,推荐直接用std::unique_ptr替代裸指针。智能指针本身就具备正确的移动语义,会自动将源对象的指针置空,这样你完全不需要自定义移动赋值运算符,编译器生成的默认版本就能处理所有成员:
#include <memory> struct Handle { std::unique_ptr<int> ptr_to_something; int member1; int member2; int member3; // 无需任何自定义移动赋值,新增成员也不用修改代码 };
这种方式不仅更简洁,还能避免手动管理内存带来的泄漏、悬挂指针等问题。
内容的提问来源于stack exchange,提问作者Zebrafish
相关产品推荐
相关产品推荐

