0

この状況でコピー省略が発生しますか? 言い換えれば、コピー省略を使用する最新のコンパイラは、ここでコピー コンストラクターを呼び出すことを回避しますか?

class BigObj{};

BigObj fun()
{
  BigObj b;
  return b;
}
int main()
{
  BigObj *pb = new BigObj(fun());
}

オブジェクトをポインターに格納することを目指しています。オブジェクトは関数によって返されます。コピーせずに保存したい。

C++11が使えない

4

2 に答える 2

1

IMO あなたが達成しようとしていることは完全には明らかではありません。動的割り当てを使用する場合、関数は単純に次のようにする必要があります。

BigObj * fun()
{
  return new BigObj;
}
int main()
{
  BigObj *pb = fun();
}

...そして、面倒を省きます。

回答の以前のリビジョンとは対照的に、完全に分析できる静的コンテキストにある限り、コンパイラーはかなりの量の作業を省略できることが判明しました。

class C {
public:
    C() {qDebug() << "C created";}
    C(const C & o) { qDebug() << "C copied"; }
};

C foo() {
    C c;
    qDebug() << &c;
    return c;
}

...
    C c = C(foo()); // note that `C c = ` is also copy construction
    qDebug() << &c;

出力は、両方のインスタンスが同じアドレスを持っていることを確認するため、ローカルのコンテキストであっても、インスタンスは実際には のスタック フレームに格納されませんfoo

変更:

C * cp = new C(foo());
qDebug() << cp;

驚いたことに、値コピーによる戻り値コピーとコピー コンストラクターの両方を省略して、同じアドレスも出力しました。cinfooは、によって割り当てられたメモリ チャンクに直接構築されnewます。

結論として、C++ コンパイラは、考えられるあらゆる最適化の分析と実行において非常に優れています。

最初と 2 番目のケースでそれぞれ最適化をオフにします。

C created
0x28fd97
C copied
C copied
C copied
0x28fdeb

...

C created
0x28fd97
C copied
C copied
0x34fd00
于 2015-08-07T07:36:20.763 に答える
0

RVO は、標準で許可されていますが、特に要求されていないものの 1 つです。とは言っても、ほとんどの最新のコンパイラ (少なくとも、適切な最適化設定が有効になっている) はそれを実装します。ただし、保証が必要な場合は、コンパイラのドキュメントを読む必要があります。

とにかくオブジェクトを動的に割り当てることが目的なので、呼び出された関数が動的割り当てを行うように例を変更するだけです。(OPのコード)の代わりに;

BigObj fun()
{
    BigObj b;
     //   presumably the point of fun() is that some initialisation
     //     of b occurs here
    return b;
}
int main()
{
    BigObj *pb = new BigObj(fun());
}

私は単に使用します

BigObj *fun()
{
    BigObj *b = new BigObj;
     //   presumably the point of fun() is that some initialisation
     //     of *b occurs here
    return b;
}
int main()
{
    BigObj *pb = fun();
}

BigObjをまとめてコピーする可能性を排除します。コピーされるのはポインターの値だけです。したがって、コンパイラは、オブジェクトの不要な作成とコピーを回避するため、上記を最適化するために C++11 移動コンストラクターの存在に依存しません。これにより、C++11 を使用しないという OP の必要性が満たされます。

明らかに、どちらの場合でも、演算子 new の使用法を対応する演算子 delete と一致させることをお勧めします。

于 2015-08-07T07:33:41.523 に答える