开发者

Should small simple structs be passed by const reference?

I have always been taught that non-p开发者_如何学Pythonrimitive types should be passed by const reference rather than by value where possible, ie:

void foo(std::string str);//bad
void foo(const std::string &str);//good

But I was thinking today that maybe actually some simple user defined types may actually be better passed by value eg:

class Vector2
{
public:
    float x, y;
    ...constructors, operators overloads, utility methods, etc...
};

void foo(Vector2 pos);
void foo(const Vector2 &pos);//is this really better than by value?
void foo(float x, float y);//after all isn't by value effectively doing this?

My thought is that by passing the Vector2 by reference, it is actually more expensive than passing by value since the compiler is now using a pointer and dereferencing to access the const Vector2 &pos version?

Is this the case? Are simple objects best off passed by value? Where should the line be drawn?


Yes, simple objects should be passed by value. The line has to be drawn according to the architecture. If in doubt, profile.


Just as a matter of policy I pass any object that isn't a basic C data type by const reference. Its much easier to remember that way.


Passing by const reference avoids the construction of a new object. If your constructor is non-trivial, e.g., it allocates memory, you will be much better off passing by const reference than by value.

In the C# world, you make this decision by choosing whether to make something a class or a struct. Classes use reference semantics while structs use value semantics. Everything I've ever read says that you should generally choose to make everything a class unless it is very small, i.e., on the order of 16 bytes. If you are looking for a cut-off for when to pass by value versus const reference in C++, 16 bytes seems like a reasonable threshold.


An older, yet lucid, analysis of the ins-n-outs of passing parameters can be found at http://www.ddj.com/184403855. Of course c++0x obviates a lot of such issues with move semantics, but the paper provides a lot of justification for why move semantics are desirable.


One factor I've not seen mentioned is what the routine is going to do with the passed-in value. Unless the routine is expanded inline, manipulating data which are passed by reference will require more code than manipulating data which are passed by value. If the fields of the passed-in structure will on average be accessed less than once each, this extra overhead will be small compared with the overhead of copying the structure. If they will on average be accessed many times each, it would likely be better to have them on the stack. If the interface is already set as pass-by-reference for a structure which is heavily accessed, it may make sense for the called routine to copy all parts that are of interest. On the other hand, if the called routine is going to copy much or all of a structure anyway, it may as well be passed by value.


My thought is that by passing the Vector2 by reference, it is actually more expensive than passing by value since the compiler is now using a pointer and dereferencing to access the const Vector2 &pos version

It would be true if you passed an object where size_of(object) < size_of(pointer_to_object). For example, char const& might be more expensive than char

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜