I am aware of the differences between pass by value, reference or pointer in the general case. However, my question is about special case about a container with simple structure.
Assuming this case:
class image{
image()=default;
image(image const&)=default;
~image()=default;
int w;
int h;
uchar* data;
}
When passing an object of this class what copied are just two integers and pointer not the whole data. In this case is there purpose to passing it by reference ? Or is there a purpose to not passing it by reference?
The thing that triggered this question is that I have read that iterators
in C++ were designed to be light and to be passed by value. So, I think that this concept may be applied to classes that represent a container to actual data no a data.
2) For passing large sized arguments: If an argument is large, passing by reference (or pointer) is more efficient because only an address is really passed, not the entire object.
Pass-by-references is more efficient than pass-by-value, because it does not copy the arguments. The formal parameter is an alias for the argument. When the called function read or write the formal parameter, it is actually read or write the argument itself.
As a rule of thumb, passing by reference or pointer is typically faster than passing by value, if the amount of data passed by value is larger than the size of a pointer.
@BjörnPollex Yes! I forgot to mention that.
Imho, the best guidelines on how to pass arguments can be found in Herb Sutters excellent talk Back to the Basics! Essentials of Modern C++ Style. In your particular case, passing by value would be the best option, as your struct is cheap to copy.
.
With the default copy constructor, any copy will be shallow and will not make a copy of the memory pointed to by data
. So when you pass by reference, only the two integers and pointer will be passed, for a total of approximately 12 bytes (depending on your architecture, i.e. pointer size).
That difference is so small, that it does not really matter whether you pass it by value or by reference. The latter may be slightly faster because the pointer can probably always be passed in via a CPU register and the 12 bytes may not, but that is really micro-optimization.
Personally I pass anything but primitive types by (const
) reference, by default, unless I have a reason not to (see jupp0r's answer). Major advantage during development is that as the class grows I don't have to worry about when it becomes too big and change all my functions to pass by reference.
As far as the default C++ iterators go: note that they are meant to basically be just pointers. In fact I know that for Microsoft Visual C++ compiling in Release mode with optimizations enabled, iterators for contiguous data structures such as std::vector
will reduce to just that. I am not aware if other compilers do this as well, I would think so. However you will notice that if you disable optimizations, then suddenly there is a difference between writing it++
and ++it
in loop increments, for example - purely because of the additional copy operation in the former case. So even "cheap to copy" may have an impact if you do it often enough. As usual: when worried about performance, measure and decide based on the numbers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With