Это то, что я сделал изначально.
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
A a4 = 123;
эквивалентно
A a4 = A(123); // The RHS is a temporary A object.
Это работает для первого случая, так как есть конструктор, который принимает A const&
в качестве типа аргумента.
Это не работает, если тип аргумента A&
, Временный объект может использоваться, когда тип аргумента A const&
не когда это A&
,
Для случая A a4 = 123;
когда объект «а4» строится, утверждение
A a4 = 123;
разбивается компилятором как
A a4 = A(123);
В приведенном выше утверждении конструктор с одним аргументом, т.е. A(int)
используется для преобразования целочисленного значения «123» во временный объект & этот временный объект копируется в объект «a4» с помощью конструктора копирования. C ++ не позволяет передавать временные объекты по неконстантной ссылке, потому что временные объекты имеют значение rvalue, которое нельзя привязать к ссылке на неконстантную.
Таким образом, в общем, если вы не передаете свой аргумент с квалификатором const, то вы не можете создавать копии const объектов.
Еще один похожий пример для лучшего понимания:
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*/}
^~~~