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.
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
Monthis the size of anint:MonthSo in general, returning by const reference is an optimization chosen to prevent what would be a costly copy.
Reason 2:
staticmakes it worseUnlike 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