复制初始化不起作用?
#include <iostream>
using namespace std;
class Test {
public:
Test() {
cout << "Default constructor called." << endl;
}
Test(Test &obj) {
cout << "copy constructor called." << endl;
}
Test& operator=(const Test &obj) {
cout << "copy assignment called." << endl;
return *this;
}
~Test() {
cout << "destructor called." << endl;
}
};
Test func(Test test) {
cout << "func called" << endl;
return test;
}
int main(int argc, char* argv[]) {
Test t1;
Test t2 = func(t1); // No matching constructor for initialization for 'Test'
return 0;
}
我正在学习C++。我写了一些测试代码来了解复制初始化和复制分配。现在我无法弄清楚为什么第二项任务不能工作。复制初始化不起作用?
rvalue无法修改,在这种情况下,应该将其视为常量引用const Test& obj
。所以当你将t1
转换为func
中的test
时,这是可以的,因为t1
是一个左值,但不是从返回值构造t2
时,这是一个xvalue(分类为右值)。
总之,你的拷贝构造函数的签名是错误的,因为它只接受左值。
第10行的以下补丁使代码对我有用。
Test(const Test &obj) {
^~~~~
这是关于cppreference.com上copy constructor的文章。请参阅语法部分。
另外,rvalue制品,其读取
右边的值可以被用于初始化一个const左值参考,在这种情况下,由右值标识的对象的寿命延长到参考端部的范围。
附:你也可以使用移动语义(C++ 11),它只接受右值。写这样的移动构造函数并不难:
Test(Test&& obj) ...
允许复制构造函数修改源对象,并且不必接受const引用。 –
@ M.M突然意识到出了什么问题。修正了。 – iBug
您的副本构造函数允许修改被复制的对象。
声明
Test t2 = func(t1);
会的func()
的返回值存储在一个临时的,然后复制到t2
。但是,这需要一个接受const
引用的拷贝构造函数,因为临时文件不能绑定到非const
引用。 (从技术上讲,编译器允许临时删除,但仍然需要为您的代码发出诊断信息,假设它已经创建了临时文件,换句话说,复制构造函数必须为const
)。
更改复制构造函数以接受const
参考。
Test(Test const &obj) {
拷贝构造函数签名是错误的,应该是'测试(const的测试和OBJ)'不'测试(测试和OBJ)' – Galik
编译器会告诉你响亮而明确:“类型的非const引用无效初始化'测试&'“。所以,使你的拷贝构造函数的参数成为一个const引用(这是正常的情况),它将起作用。 – Rene
@Galik谢谢你,它现在有用! –