我试图理解复制构造函数,请理解它是如何工作的。
案例1
class fruit{
public: int i;
fruit(int j){
i = j;
}
};
int main(){
fruit f1 = fruit(2); // works fine when no user defined copy constructor
return 0;
}
案例2
class fruit{
public: int i;
fruit(fruit &f){
i = f.i + 1;
}
fruit(int j){
i = j;
}
};
int main(){
fruit f1 = fruit(2); // error no matching call fruit::fruit(fruit) why?
return 0;
}
案例3
class fruit{
public: int i;
fruit(){
i = 0;
}
};
int main(){
fruit f2;
fruit f1 = fruit(f2); // works fine when no user defined copy constructor
return 0;
}
案例4
class fruit{
public: int i;
fruit(){
i = 0;
}
fruit(fruit &f){
i = f.i + 1;
}
};
int main(){
fruit f2;
fruit f1 = fruit(f2); // error no matching call fruit::fruit(fruit)
return 0;
}
Technically 'fruit(f2)' must be valid because
f2 can be passed by reference to fruit(fruit &f). right? but why error?
为什么我会在Case 2
和Case 4
中收到错误消息?这是因为我创建了用户定义的复制构造函数?如果原因是用户定义的复制构造函数,甚至编译器提供了默认的复制构造函数。像内部fruit(fruit &)
那样即使这样,编译器提供的程序也可以使用复制构造函数。为什么它不会在Case 1
和Case 3
我理解当用户定义复制构造函数时,所有构造函数都被=
阻止。 =
只能调用复制构造函数。但是必须有一个类的复制构造函数可以由用户或编译器。如果它是由编译器提供的,那么它也必须引发错误。但这不是为什么?
答案 0 :(得分:2)
这不是与拷贝构造函数特别相关的问题;非const
左值引用无法绑定到临时值。
以下代码已编译:
fruit f1;
fruit f2(f1);
因为f1
在传递时不是临时的。
尽管如此,你仍然想要临时工作,所以写下你的复制构造函数:
fruit(const fruit& f) {
i = f.i + 1;
}
您的案例1和3成功,因为编译器能够生成自己的"默认"复制构造函数看到你没有提供一个,这与你不一样 - 它做得正确。 : - )
答案 1 :(得分:1)
fruit f1 = fruit(f2);
对于fruit(f2),将创建临时的,不能绑定到非const引用。你必须使用follwoing copy constrcutor才能工作: -
fruit(const fruit& f)