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

时间:2012-07-07 15:24:42

标签: 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));

更改函数是否有任何缺点,以便它们将静态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;
};

我认为第二个版本比第一个版本效率更高。

2 个答案:

答案 0 :(得分:7)

原因1:不是更好。

按值返回会产生复制整个对象的成本。

通过引用返回会导致复制有效指针的成本,以及解除引用该指针的成本。

由于Month的大小为int

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

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

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

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

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

另见Vaughn Cato的回答

另见ildjam的评论

答案 1 :(得分:3)

有些编译器不会使用包含静态局部变量的内联方法,而内联是这里最重要的性能优化。