I have a Particle System Engine in my C++ project and the particles themselves are just structs of variables with no functions. Currently, each particle (Particle) is updated fr
Setters and getters have a performance overhead when not optimized out. They are almost always optimized out on compilers that do link time optimization. And on compilers that do not, if they have knowledge of the function body (ie not just a prototype) it will be optimized out.
However, you use getters and setters are there because you might want getting or setting that variable to have additional side effects. Like changing the position of an object also changes the position of nearby objects in a physics simulation or some such.
Finally, the overhead of a getter and setter operation, within the context of optimized code, is very small, not worth worrying about unless the code is hot. And if it's hot, it's SO EASY to just move the getter or setter to the header file and inline it.
So to sum up, getters and setters are well worth the minor or non-existent overhead, as it allows you to specify very specifically what can and cannot happen with your object, and it also allows you to marshal any changes.
I have a different opinion to this than the previous answers.
Getters and setters are signs that your class isn't designed in a useful way: if you don't make the outer behaviour abstract from the internal implementation, there's no point in using an abstract interface in the first place, you might as well use a plain old struct.
Think about what operations you really need. That's almost certainly not direct access to the x- y- and z-coordinates of position and momentum, you rather want to treat these as vector quantities (at least in most calculations, which is all that's relevant for optimisation). So you want to implement a vector-based interface*, where the basic operations are vector addition, scaling and inner product. Not component-wise access; you probably do need to do that sometimes as well, but this can be done with a single std::array<double,3> to_posarray()
member or something like that.
When the internal components x
, y
... vz
aren't accessible from the outside, you can then safely change the internal implementation without braking any code outside your module. That's pretty much the whole point af getters/setters; however when using those these there's only so much optimisation you can do: any real change of implementation with inevitably make the getters much slower.
On the other hand, you can optimise the hell out of a vector-based interface, with SIMD operations, external library calls (possibly on accelerated hardware like CUDA) and suchlike. A "batch-getter" like to_posarray
can still be implemented reasonably efficient, single-variable setters can't.
*I mean vector in the mathematical sense here, not like std::vector
.
There could be various answers to this question, but I put my thoughts here.
For the performance, the cost can be mostly ignored for simple POD type. But there 's still cost, and it depends on what type you return. For particle, there couldn't be much data. If this is a image class (like OpenCV cv::Mat), or 3d data (like PolyData in VTK), it is better that setter/getter deals with pointers/iterators than the actual data to avoid memory allocation problem.
When you want to template things, the setter/getter can be a lot useful to avoid inexplicit type conversion. A setter/getter can be a way to access private/protected member, which is also allows you to avoid using x as the common name of variable. More over, the setter/getter can return a Lvalue reference which allows you to do particle.getX() = 10.0 ;
Getters and setters allow your code to evolve more easily in the future, if getting and setting turn out to be slightly more complicated tasks. Most C++ compilers are smart enough to inline those simple methods and eliminate the overhead of the function call.