关于 C++ 中复制构造函数的混淆

Confusion about Copy Constructor in C++

提问人:msc 提问时间:8/24/2018 最后编辑:msc 更新时间:8/24/2018 访问量:102

问:

法典:

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) 
         ^

为什么编译器在最后一种情况下会出错?

C++ 参考 C++14 复制构造函数

评论


答:

7赞 songyuanyao 8/24/2018 #1

A a2 = func();复制初始化,将从 via copy 构造函数返回的对象进行初始化。 按值返回,所以它返回的是临时的,它不能绑定到对非常量的左值引用(即),这就是你得到错误的原因。a2func()func()A &

Temporary 可以绑定到 lvalue-reference to(或 rvalue-reference),因此将参数类型更改为 (或添加移动构造函数) 将使其正常工作。constconst A &t

顺便说一句:与复制构造函数无关,而是复制赋值运算符。您没有为 声明它,并且隐式声明的复制赋值运算符作为参数,然后就可以了。a2 = func();Aconst A&

顺便说一句2:不返回任何内容。请注意,从非空函数的末尾流出而不返回会导致 UB。func()

评论

0赞 taskinoor 8/24/2018
既然没有 return 语句,那么不是调用 UB 吗?我在这里错过了什么?func()A a2 = func();
4赞 songyuanyao 8/24/2018
@taskinoor 是的,是UB。