Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is foo->bar->foobar considered bad style? And how to avoid without adding code?

Our C++ professor mentioned that using the result of operator-> as input into another operator-> is considered bad style.

So instead of writing:

return edge->terminal->outgoing_edges[0];

He would prefer:

Node* terminal = edge->terminal;
return terminal->outgoing_edges[0];
  1. Why is this considered bad style?
  2. How could I restructure my program to avoid the 'bad style' but also avoid the extra line of code that is created as per the above suggestion?
like image 964
HorseloverFat Avatar asked Jul 10 '12 13:07

HorseloverFat


2 Answers

There's a number of reasons.

The Law of Demeter gives a structural reason (note that your C++ professors code still violates this though!). In your example, edge has to know about terminal and outgoing_edges. That makes it tightly coupled.

As an alternative

class Edge {
 private:
   Node* terminal;
 public:
   Edges* outgoing_edges() {
      return terminal->outgoing_edges;
   }
}

Now you can change the implementation of outgoing_edges in one place without changing everywhere. To be honest, I don't really buy this in the case of a data structure like a graph (it is tightly coupled, edges and nodes can't escape each other). This'd be over-abstraction in my book.

There's the null dereference problem too, in the expression a->b->c, what if b is null?

like image 134
Jeff Foster Avatar answered Oct 17 '22 22:10

Jeff Foster


You should ask your professor as to why he considers it bad style. I don't. I would however consider his omission of the const in the declaration of terminal to be bad style.

For a single snippet like that, it's probably not bad style. However consider this:

void somefunc(Edge *edge)
{
   if (edge->terminal->outgoing_edges.size() > 5)
   {
        edge->terminal->outgoing_edges.rezize(10);
        edge->terminal->counter = 5;
   }
   ++edge->terminal->another_value;
}

This is starting to get unwieldy - it is difficult to read, it is difficult to write (I made approximately 10 typos when typing that). And it requires a lot of evaluation of the operator-> on those 2 classes. OK if the operator is trivial, but if the operator does anything exciting, it's going to end up doing a lot of work.

So there's 2 possible answers:

  1. Maintanability
  2. Efficiency

And a single snippet like that, you can't avoid the extra line. In something like the above, it'd have resulted in less typing.

like image 23
Tom Tanner Avatar answered Oct 17 '22 21:10

Tom Tanner