1

変換コンストラクターを理解しようとしています。次のコードを使用しています

class cls 
{
public:
  cls()
  {
      std::cout << "Regular constructor \n";     ---> Line A
  }
  cls (int a) //Constructing converter
  {
      std::cout << "Int constructor \n";         ---> Line B
  }

  cls (cls& d) //Copy constructor
  {
      std::cout << "Copy constructor \n";        ---> Line C
  }
};


int main()
{
    cls d;
    std::cout << "-----------------------\n";
    cls e = 15; //int constructor then copy constructor
        return;
}

今、私cls e = 15は、このステートメントが行 B (Conversion Cont) を呼び出し、次に行 C (コピー コンストラクター) を呼び出すことを想定していたというステートメントに混乱していますが、それは行 B のみを呼び出しcls e = 15ましたcls e = cls(15)。だから私は試してみcls e = cls(15)ましたが、これもB行のみを提供します。

cls e = cls(15)//変換コンストラクターの後にコピー コンストラクターが続くことを期待していましたが、明らかに間違っていました。何が起こっているのかについての説明をいただければ幸いです

4

3 に答える 3

3

これは、コピー省略コンパイラの最適化によるものです。コンパイラは、特定のケースでコピー コンストラクター呼び出しを省略できます。ご覧のとおり、この最適化が実際に行われています。次の呼び出しを想定するのは正しいです。

  • 変換コンストラクターと
  • コンストラクターのコピー

ただし、この場合、2 番目の呼び出しは、戻り値の最適化を使用して、コンストラクターによって省略/削除/最適化されます。eコンパイラは、一時オブジェクトを作成してから にコピーするのではなく、オブジェクトを に直接構築しますe

GCC を使用している場合は、-fno-elide-constructorsオプションを使用して copy-elision を無効にすることができ、期待どおりの結果が得られるはずです。

于 2013-08-25T13:57:22.260 に答える
0

コンパイラは、として知られているコピーコンストラクタを呼び出さないようにコードを最適化しているようですcopy elision

詳しくはこちらをご覧ください。

基本的にコピー省略では、コンパイラはコードを最適化し、不要な中間一時オブジェクトを省略します。

于 2013-08-25T13:58:01.930 に答える
0

cls e = 15あなたはそれが と同じであることについて正しいですcls e = cls(15)。これは、 yourcls(int a)が明示的に宣言されていないためです。次は、コンパイラのコピー省略の最適化です。

于 2013-08-25T13:59:48.293 に答える