I have this class:
struct Handle
{
int* ptr_to_something;
void operator=(Handle&& other)
{
ptr_to_something = other.ptr_to_something;
this->member1 = other.member1;
this->member2 = other.member2;
this->member3 = other.member3;
other.ptr_to_something = nullptr;
}
int member1;
int member2;
int member3;
};
What I hate is possibility that new members might be added, and I'll have to remember to add them to the operator. Is there possibly a way I could call the default operator and then add that teensy little but that sets the other ptr to null after it?
You can have a base class with a defaulted move operator:
struct HandlerBase {
int* ptr_to_something;
int member1;
int member2;
int member3;
};
struct Handler : HandlerBase {
void operator=(Handler&& other) {
HandlerBase::operator=(std::move(other));
other.ptr_to_something = nullptr;
}
};
Or you can make the defaulted move operator do what you want by making ptr_to_something
a class whose operator=
does what you want:
template<typename T>
struct PtrThatResetsOnMove {
T* value;
constexpr explicit(false) PtrThatResetsOnMove(T* value) noexcept : value(value) {}
constexpr PtrThatResetsOnMove(PtrThatResetsOnMove&& other) noexcept : value(std::exchange(other.value, nullptr)) {}
constexpr PtrThatResetsOnMove& operator=(PtrThatResetsOnMove&& other) noexcept {
value = std::exchange(other.value, nullptr);
return *this;
}
~PtrThatResetsOnMove() = default;
};
struct Handler {
PtrThatResetsOnMove<int> ptr_to_something;
int member1;
int member2;
int member3;
};
Or you can put the other members in a different class with a defaulted operator:
struct HandlerMembers {
int member1;
int member2;
int member3;
};
struct Handler {
int* ptr_to_something;
HandlerMembers members;
void operator=(Handler&& other) {
ptr_to_something = other.ptr_to_something;
members = std::move(other.members);
other.ptr_to_something = nullptr;
}
};