2

これは私がもともとやったことです。

class A
{   public:
    A()         { std::cout << "\ndefault constructor";     }
    A(const A&) { std::cout << "\ncopy constructor";        }
    A(int)      { std::cout << "\nconversion constructor";  }
};

A a0;           // print default constructor
A a1(a0);       // print copy constructor       note : direct initialization
A a2 = a0;      // print copy constructor       note : copy initialization
A a3(123);      // print conversion constructor     note : direct initialization
A a4 = 123;     // print conversion constructor     note : copy initialization (create a temp object from int)

しかし、クラス A を次のように少し変更すると (コピー コンストラクターの const を削除)、最終行でコンパイル エラーが発生するのはなぜですか? ありがとうございました

class A
{   public:
    A()         { std::cout << "\ndefault constructor";     }
    A(A&)       { std::cout << "\ncopy constructor";        }
    A(int)      { std::cout << "\nconversion constructor";  }
};

A a0;           // print default constructor
A a1(a0);       // print copy constructor       note : direct initialization
A a2 = a0;      // print copy constructor       note : copy initialization
A a3(123);      // print conversion constructor     note : direct initialization
//A a4 = 123;   // compile error
4

2 に答える 2

5
A a4 = 123;

と同等です

A a4 = A(123); // The RHS is a temporary A object.

A const&引数の型としてa を取るコンストラクターがあるため、これは最初のケースで機能します。

引数の型が の場合、これは機能しませんA&。一時オブジェクトは、引数の型がA const&の場合ではなく、の場合に使用できますA&

于 2016-11-19T05:23:20.340 に答える
2

の場合A a4 = 123;、オブジェクト「a4」が構築されているとき、ステートメント

A a4 = 123;

コンパイラによって次のように分解されます

A a4 = A(123);

上記のステートメントでは、1 つの引数コンストラクター ieA(int)が整数値「123」を一時オブジェクトに変換するために使用され、その一時オブジェクトがコピー コンストラクターを使用してオブジェクト「a4」にコピーされます。一時オブジェクトは右辺値であり、非 const への参照にバインドできないため、C++ では非 const 参照によって一時オブジェクトを渡すことはできません。

したがって、一般的に、const 修飾子を使用して引数を渡さない場合、const オブジェクトのコピーを作成することはできません。

理解を深めるためのもう 1 つの同様の例:

class Test
{
   /* Class data members */
public:
   Test(Test &t) { /* Copy data members from t*/}
   Test()        { /* Initialize data members */ }
};

Test fun()
{
    cout << "fun() Called\n";
    Test t;
    return t;
}
int main()
{
    Test t1;
    Test t2 = fun();  //compilation error with non-const copy constructor
    return 0;
}

$g++ -o main *.cpp
main.cpp: In function ‘int main()’:
main.cpp:22:18: error: cannot bind non-const lvalue reference of type ‘Test&’ to an rvalue of type ‘Test’
     Test t2 = fun();
               ~~~^~
main.cpp:8:4: note:   initializing argument 1 of ‘Test::Test(Test&)’
    Test(Test &t) { /* Copy data members from t*/}
    ^~~~
于 2016-11-19T18:30:10.543 に答える