3

次のように作成されたIntegerクラスのbinary+をオーバーロードしようとしました。

const Integer operator+(const Integer& left,const Integer& right) 
{
    return Integer(left.i + right.i);
}

 const Integer operator+(const Integer& left,const Integer& right)
 {
     Integer tmp(left.i + right.i);
     return tmp;
 }

私が学んだことは、最初のケースでは一時的なIntegerオブジェクトが作成されて返され、2番目のケースではコンストラクター呼び出しを使用した通常のオブジェクト作成、次にコピーしてからデストラクタの呼び出しが行われることです。Eceklが最初のものについて言ったことは、コンパイラーがオブジェクトを外部の戻り値の場所に直接構築することによってこれを利用するということです。これから何を推測しますか?戻り値の最適化について読みましたが、場所に直接コピーしても意味がわかりませんでした。

4

1 に答える 1

7

まったく違いはありません。ほとんどの場合、適切なコンパイラは2番目の形式を最初の形式に最適化します。また、を返すときに、名前付き戻り値最適化(NRVO)tmpによるコピー/移動の省略を実行します。

コードが読みやすくなったり、保守やデバッグが容易になったりする場合は、2番目の形式を使用することをお勧めします。パフォーマンスに関心がある場合、理由はありません(コンパイラーの最適化をオフにしない限り、それはそもそもパフォーマンスに興味がないことを示唆します)。

ただし、aを返すことconst Integerはあまり意味がないことに注意してください。Integer値で返すので、むしろ:を返す必要があります。

Integer operator + (const Integer& left, const Integer& right) 
{
    return Integer(left.i + right.i);
}

最後の注意として、これは次のように書き直すこともできます。ただしInteger、非explicitコンストラクターがint(1つの引数を受け入れるコンストラクターは通常、厄介な暗黙の変換を回避するようにマークされているため、通常はそうではないことに注意してください)。explicit

Integer operator + (const Integer& left, const Integer& right) 
{
    return left.i + right.i;
}
于 2013-03-10T15:30:09.203 に答える