For context, the actual class I'm working with is considerably more complicated and larger than what I'm showing here, but I'm using this just as an example.
struct Vector {
int x, y;
Vector() : Vector(0,0) {}
Vector(int x, int y) : x(x), y(y) {}
};
I'd like to add operator overloads to allow Vectors to be added and subtracted from each other.
Vector& operator+=(Vector const& v) {
x += v.x;
y += v.y;
return *this;
}
Vector operator+(Vector const& v) const {
return Vector(*this) += v;
}
Vector& operator-=(Vector const& v) {
x -= v.x;
y -= v.y;
return *this;
}
Vector operator-(Vector const& v) const {
return Vector(*this) -= v;
}
However, This code can allow unfortunate constructions:
int main() {
Vector & a = Vector(1,2) += Vector(5,4);//This compiles and invokes undefined behavior!
std::cout << a.x << ',' << a.y << std::endl;//This isn't safe!
}
So I rewrote the code to be mindful of whether the object is an L-value or R-value:
Vector& operator+=(Vector const& v) & {
x += v.x;
y += v.y;
return *this;
}
Vector&& operator+=(Vector const& v) && {
return std::move(*this += v);
}
Vector operator+(Vector const& v) const {
return Vector(*this) += v;
}
Vector& operator-=(Vector const& v) & {
x -= v.x;
y -= v.y;
return *this;
}
Vector&& operator-=(Vector const& v) && {
return std::move(*this -= v);
}
Vector operator-(Vector const& v) const {
return Vector(*this) -= v;
}
So my remaining question is, even though this code compiles and does what I'm expecting, is this code safe and free of unexpected Undefined Behavior?
Aucun commentaire:
Enregistrer un commentaire