3

効果的な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));

月への静的定数参照を返すように関数を変更することの欠点はありますか?

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番目のバージョンは最初のバージョンよりも少し効率的だと思いました。

4

2 に答える 2

8

理由1:それは良くありません。

値で返すと、オブジェクト全体をコピーするコストが発生します。

参照によって返すには、事実上ポインターであるものをコピーするコストに加えて、そのポインターを逆参照するコストが発生します。

Monthのサイズなのでint

  • 参照のコピーは、Month
  • その参照にアクセスするたびに、間接参照が発生します。

したがって、一般に、const参照による戻りは、コストのかかるコピーを防ぐために選択された最適化です。

理由2:static悪化させる

Cとは異なり、C ++は、関数の最初の呼び出し時に関数内の静的変数が作成されることを約束します。

実際には、これは、関数へのすべての呼び出しが、それが最初の呼び出しであるかどうかを判断するために、いくつかの目に見えないロジックで開始する必要があることを意味します。

VaughnCatoの回答も参照してください

ildjamのコメントも参照してください

于 2012-07-07T15:29:03.177 に答える
3

一部のコンパイラは静的ローカル変数を含むメソッドをインライン化しません。インライン化は、ここで最も重要なパフォーマンスの最適化です。

于 2012-07-07T15:31:43.247 に答える