Код:
class A
{
public:
A()
{
cout<<"Defualt Constructor"<<endl;
}
A(A &t)
{
cout<<"Copy Constructor"<<endl;
}
};
A func()
{
cout<<"In func"<<endl;
}
int main()
{
A a1;
A a2;
a2 = func();
return 0;
}
Программа работает нормально. Кроме того, если я вызываю такую функцию:
A a2 = func();
и добавьте квалификатор const в аргумент копироватьконструктор, например:
A(const A &t)
{
cout<<"Copy Constructor"<<endl;
}
Кроме того, работает нормально.
Но, если удалить const из аргумента конструктор копирования, например:
A(A &t)
{
cout<<"Copy Constructor"<<endl;
}
и вызвать функцию func()
A a2 = func();
Компилятор выдает ошибку:
error: invalid initialization of non-const reference of type 'A&' from an rvalue of type 'A'
A a2 = func();
^
prog.cpp:13:9: note: initializing argument 1 of 'A::A(A&)'
A(A &t)
^
Почему компилятор выдает ошибку в последнем случае?





A a2 = func(); - это копировать инициализацию, a2 будет инициализирован из объекта, возвращаемого func() через конструктор копирования. func() возвращается по значению, поэтому то, что он возвращает, является временным, которое не может быть привязано к lvalue-reference к неконстантному (то есть A &), поэтому вы получаете ошибку.
Temporary может быть привязано к lvalue-reference к const (или rvalue-reference), поэтому изменение типа параметра на const A &t (или добавление конструктора перемещения) заставит его работать нормально.
Кстати: a2 = func(); не имеет ничего общего с конструктором копирования, а только с оператором присваивания копии. Вы не объявили это для A, а неявно объявленный оператор присваивания копии принимает const A& в качестве параметра, тогда все в порядке.
BTW2: func() ничего не возвращает. Обратите внимание, что вытекает из конца непустой функции без возврата ведет к UB.
@taskinoor Да, это УБ.
Поскольку
func()не имеет оператора возврата, развеA a2 = func();не вызывает UB? Что мне здесь не хватает?