Home > database >  Why implement specific functions to retrieve data rather than retrieving directly when overloading a
Why implement specific functions to retrieve data rather than retrieving directly when overloading a

Time:09-22

C newbie here.

I'm reading the book Data Structures and Algorithm Analysis in C (M. A. Weiss), where the implementation of const_iterator and iterator class nested in a user-defined List class of <typename Object> was given.

Here's a snippet of it.

class const_iterator
{
public:
    const Object& operator* () const
    { return retrieve(); }

protected:
    Node* current_;

    Object& retrieve() const
    { return current_->data_; }
};

class iterator : public const_iterator
{
public:
    Object& operator* ()
    { return const_iterator::retrieve(); }

    const Object& operator* () const
    { return const_iterator::operator*(); }
};

I really don't get why did the author bother to write the retrieve function just to retrieve the data, whose body is exactly all it takes to do so. If I were to implement the three overload functions, I would naturally write return current_->data_ or return *this->current_->data_. I mean, even if it's equivalent, I wouldn't come up with this kind of idea either.

This question seems trivial, and I'm asking out of pure curiosity. In my limited knowledge of C , calling functions has a performance cost. Though this could be optimized out by the compiler, I prefer the code to be logically the most efficient at least on paper.

It gets even stranger that for const return values, the author used operator* instead of retrieve in consistency.

What's the benefit of jumping between retrieve functions rather than a simple return expression?

CodePudding user response:

I think the usage of intermediary function may just be due to the preference of the author. Usually such style is used in order to perform some validation in the intermediary function(for example, checking if data_ is nullptr, or if data_ satisfies some condition which is imposed by the problem the code tries to solve). But I have seen some people who even if there is no need for some kind of validation, still use this style. For example when you write

Object& operator* ()
{ return const_iterator::retrieve(); }

you expect that retrieve function will not return you corrupted data. And even when you get a corrupted value, you immediately know that there is a problem in retrieve function, and you can just solve the issue by investigating it. If you didn't have an intermediary function, you had to investigate every place where you written the alternative code of retrieve. Also, it is much better to have a function which deals with all the raw data, and you don't deal with them anymore.

CodePudding user response:

A large advantage of funnelling everything through retrieve is that it is one place.

If you want to change the behaviour, you change it in the one place. If you want a debugger to stop there, it's one breakpoint.

  • Related