Reputation: 2147
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
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
:
Month
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
Reputation: 64308
Some compilers won't inline methods that contain static local variables, and inlining is the most important performance optimization here.
Upvotes: 3