jpen
jpen

Reputation: 2147

Returning static const reference to object from functions

In Effective C++ (Item 18: Make interfaces easy to use correctly and hard to use incorrectly), I saw a code sample similar to the following:

class Month
{
public:
    static Month Jan()
    {
        return Month(1);
    }

    static Month Feb()
    {
        return Month(2);
    }

    //...

    static Month Dec()
    {
        return Month(12);
    }

private:
    explicit Month(int nMonth)
        : m_nMonth(nMonth)
    {
    }

private:
    int m_nMonth;
};

Date date(Month::Mar(), Day(30), Year(1995));

Are there any drawbacks of changing the functions so that they return static const reference to Month?

class Month
{
public:
    static const Month& Jan()
    {
        static Month month(1);
        return month;
    }

    static const Month& Feb()
    {
        static Month month(2);
        return month;
    }

    //...

    static const Month& Dec()
    {
        static Month month(12);
        return month;
    }

private:
    explicit Month(int nMonth)
        : m_nMonth(nMonth)
    {
    }

private:
    int m_nMonth;
};

I thought the second version is a bit more efficient than the first one.

Upvotes: 3

Views: 7460

Answers (2)

Drew Dormann
Drew Dormann

Reputation: 63755

Reason 1: It's not better.

Returning by value incurs the cost of copying the entire object.

Returning by reference incurs the cost of copying what's effectively a pointer, plus the cost of dereferencing that pointer.

Since Month is the size of an int:

  • Copying a reference is no faster than copying a Month
  • Dereferencing would be incurred every time that reference is accessed.

So in general, returning by const reference is an optimization chosen to prevent what would be a costly copy.

Reason 2: static makes it worse

Unlike C, C++ promises that a static variable in a function will be constructed at the time of the function's first call.

In practice this means that every call to the function must begin with some unseen logic to determine if it's the first call.

See also Vaughn Cato's answer

See also ildjam's comment

Upvotes: 8

Vaughn Cato
Vaughn Cato

Reputation: 64308

Some compilers won't inline methods that contain static local variables, and inlining is the most important performance optimization here.

Upvotes: 3

Related Questions