3

初期化に関するこの構文について質問があります。

http://en.wikipedia.org/wiki/Copy_constructorから引用

X a = X();
// valid given X(const X& copy_from_me) but not valid given X(X& copy_from_me)               
// because the second wants a non-const X&               
// to create a, the compiler first creates a temporary by invoking the default constructor               
// of X, then uses the copy constructor to initialize a as a copy of that temporary.                
// However, for some compilers both the first and the second actually work.

#include <iostream>

class Foo
{
public:
    Foo()
    {
        std::cout << "Default Constructor called" << std::endl;
    }

    Foo(const Foo& other)
    {
        std::cout << "Copy constructor called" << std::endl;
    }

    Foo& operator=(const Foo& rhs)
    {
        std::cout << "Assignment operator called" << std::endl;
    }
};

int main()
{
    Foo b = Foo(); //case 1:default 
    Foo c = Foo(a); //case 2: copy constructor
}

ケース 1:
コピー コンストラクターでパラメーターを const から非 const に変更すると、ケース 1 はウィキペディアの期待どおりにコンパイルされません。ただし、適切なコピー コンストラクターを使用して実行すると、既定のコンストラクターのみが呼び出されます。コピーコンストラクターも呼び出さないのはなぜですか? これはコンパイル時に行われる最適化ですか?

ケース 2:
ケース 1 の答えはおそらくケース 2 の答えになるでしょうが、なぜこれはコピー コンストラクターを一度だけ呼び出すのでしょうか?

4

2 に答える 2

4
Foo b = Foo();

このフォームには、有効な一致するコピーコンストラクターが存在する必要がありますが、コピーは最適化されていない可能性があります。最適化されている可能性があるという事実は、コンストラクターが存在するという要件を緩和するものではありません。

Foo()コピーコンストラクターに非const参照を取得させると、一時的なものが生成され、一時的なものは非const参照にバインドできないため、一致しなくなります。パラメーターをconst参照にする(またはコピーc-torを破棄して、コンパイラーが生成したコピーc-torを使用する)と、一時的にconst参照にバインドできるため、機能します。

于 2012-05-24T19:45:44.047 に答える
1

X()は一時的なものであるため、非参照にバインドすることはできませんconst(ただし、MSVSにはそれを可能にする拡張機能があります)。

1)はい、それはコンパイラの最適化です

a2)存在しないため、違法です。しかし、原則として、繰り返しになりますが、コンパイラの最適化です。

于 2012-05-24T19:46:36.777 に答える