But in that case we also need to have an explanation why there are no setPosition() and setSize() methods. In my opinion, the constructor + those 2 getters is totally enough.
I'd be fine with adding the set() counter-parts as well, to be honest.
We should not overestimate the impact of copying a 2D vector
Quite true, but we also shouldn't overestimate the impact of using references.
tl;dr: premature optimization is evil. A copy being made is obvious from the return type, or DRY as you would say
I agree to DRY.
However, regarding premature optimization.. This really depends on the perspective now. Because you are prematurely optimizing as well, by NOT using a `const&` for a compound type, which is what one normally does. Just by looking at the trivial case of sf::Vector2 you drop const&. This is clearly an optimization — even a premature one. I took the time to do a little disassembly.
Compiler command used: g++ -O0 -g
Source code:
class Point {
public:
Point(float x_, float y_) : x(x_), y(y_) {}
float x;
float y;
};
class Compound {
public:
Compound() : point(0.0f, 0.0f) {}
Point get_position_new() { return Point(point.x, point.y); }
Point get_position_copy() { return point; }
const Point& get_position_ref() { return point; }
Point point;
};
int main() {
Compound foo;
Point point_new = foo.get_position_new();
Point point_copy = foo.get_position_copy();
const Point& point_ref = foo.get_position_ref();
float x, y;
x = point_new.x;
y = point_new.y;
x = point_copy.x;
y = point_copy.y;
x = point_ref.x;
y = point_ref.y;
return 0;
}
Disassembly output: (using `objdump -d -S -M intel`; only the interesting stuff)
x = point_new.x;
4005c4: f3 0f 10 45 d0 movss xmm0,DWORD PTR [rbp-0x30]
4005c9: f3 0f 11 45 f4 movss DWORD PTR [rbp-0xc],xmm0
y = point_new.y;
4005ce: f3 0f 10 45 d4 movss xmm0,DWORD PTR [rbp-0x2c]
4005d3: f3 0f 11 45 f0 movss DWORD PTR [rbp-0x10],xmm0
x = point_copy.x;
4005d8: f3 0f 10 45 c0 movss xmm0,DWORD PTR [rbp-0x40]
4005dd: f3 0f 11 45 f4 movss DWORD PTR [rbp-0xc],xmm0
y = point_copy.y;
4005e2: f3 0f 10 45 c4 movss xmm0,DWORD PTR [rbp-0x3c]
4005e7: f3 0f 11 45 f0 movss DWORD PTR [rbp-0x10],xmm0
x = point_ref.x;
4005ec: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
4005f0: f3 0f 10 00 movss xmm0,DWORD PTR [rax]
4005f4: f3 0f 11 45 f4 movss DWORD PTR [rbp-0xc],xmm0
y = point_ref.y;
4005f9: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
4005fd: f3 0f 10 40 04 movss xmm0,DWORD PTR [rax+0x4]
400602: f3 0f 11 45 f0 movss DWORD PTR [rbp-0x10],xmm0
ConclusionYou have one(!) more MOV instruction for loading the reference address needed for dereferencing `point_ref`. That's about it, not even function calls, and it's the non-optimized case. (I gave up tricking the compiler enough to get reasonable code for disassembly using -O3
) I don't know of any computer, even from the 90s, that will make a notifiable difference.
Not trying to bash here, really. Actually I wanted to know myself how big the impact is. On a second note though, you played the "Premature optimization" card, and the disassembly proves that moving away from "& for compound types" is a micro optimization and premature.
So yes: Premature optimizations ARE evil and useless.