从函数返回对象的静态const引用

jpe*_*pen 3 c++ oop

在Effective C++中(第18项:使界面易于正确使用且难以正确使用),我看到了类似于以下内容的代码示例:

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));
Run Code Online (Sandbox Code Playgroud)

更改函数是否有任何缺点,以便它们将静态const引用返回到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;
};
Run Code Online (Sandbox Code Playgroud)

我认为第二个版本比第一个版本更有效.

Dre*_*ann 7

原因1:不是更好.

按值返回会导致复制整个对象的成本.

通过引用返回会产生复制有效指针的成本,以及解除引用该指针的成本.

由于Month是一个大小int:

  • 复制引用并不比复制引用快 Month
  • 每次访问该引用时都会引发解除引用.

因此,一般来说,通过const引用返回是一个优化选择,以防止什么是昂贵的副本.

原因2:static使情况变得更糟

与C不同,C++承诺在函数第一次调用时将构造函数中的静态变量.

在实践中,这意味着对函数的每次调用都必须以一些看不见的逻辑开始,以确定它是否是第一次调用.

另见Vaughn Cato的回答

另见ildjam的评论