C++: Using '.' operator on expressions and function calls

246 views Asked by At

I was wondering if it is good practice to use the member operator . like this:

someVector = (segment.getFirst() - segment.getSecond()).normalize().normalCCW();

Just made that to show the two different things I was wondering, namely if using (expressions).member/function() and foo.getBar().getmoreBar() were in keeping with the spirit of readability and maintainability. In all the c++ code and books I learned from, I've never seen it used in this way, yet its intoxicatingly easy to use it as such. Don't want to develop any bad habits though.

Probably more (or less) important than that, I was also wondering if there would be any performance gains/losses by using it in this fashion, or unforeseen pitfalls that would introduce bugs into the program.

Thank you in advance!

8

There are 8 answers

1
Ed Swangren On BEST ANSWER

or unforeseen pitfalls that would introduce bugs into the program

Well, the possible pitfalls would be

  1. Harder to debug. You won't be able to view the results of each function call, so if one of them is returning something unexpected you will need to break it up into smaller segments to see what is going on. Also, any call in the chain may fail completely, so again, you may have to break it up to find out which call is failing.

  2. Harder to read (sometimes). Chaining function calls can make the code harder to read. It depends on the situation, there's no hard and fast rule here. If the expression is even somewhat complex it can make things hard to follow. I don't have any problem reading your specific example.

It ultimately comes down to personal preference. I don't strive to fit as much as possible on a single line, and I have been bitten enough times by chaining where I shouldn't that I tend to break things up a bit. However, for simple expressions which are not likely to fail, chaining is fine.

2
Falmarri On

Yes, this is perfectly acceptable and in fact would be completely unreadable in a lot of contexts if you were to NOT do this.

It's called method chaining.

There MIGHT be some performance gain in that you're not creating temporary variables. But any competent compiler will optimise it anyway.

0
Marlon On

I suppose what you are doing is less readable, however on the other hand, too many temporary variables can also become unreadable.

As far performance I'm sure there is a little overhead when making temporary variables but the compiler could optimize that out.

1
Puppy On

There's no big problem with using it in this way- some APIs benefit greatly from method chaining. Plus, it's misleading to create a variable, and then only use it once. When someone reads the next line, they don't have to think about all those variables that you now didn't keep.

3
Yochai Timmer On

It depends of what you're doing.

For readability you should try to use intermediate variables.
Assign calculation results to pointers, and then use them.

2
neuro On

it is perfectly valid to use it the way you showed. It is used in the named parameter idiom described in C++ faq lite for example.

One reason it is not always used is when you have to store intermediate result for performance reasons (if normalize is costly and you have to use it more than one time, it is better to store the result in a variable) or readability.

my2c

4
Sarfaraz Nawaz On
someVector = (segment.getFirst() - segment.getSecond()).normalize().normalCCW();

Not an answer to your question, but I should tell you that the behavior of the expression (segment.getFirst() - segment.getSecond()) is not well-defined as per the C++ Standard. The order in which each operand is evaluated is unspecified by the Standard!

Also, see this related topic : Is this code well-defined?

2
Emile Cormier On

Using a variable to hold intermediate results can sometimes enhance readability, especially if you use good variable names. Excessive chaining can make it hard to understand what is happening. You have to use your judgement to decide if it's worthwhile to break down chains using variables. The example you present above is not excessive to me. Performance shouldn't differ much one way or the other if you enable optimization.