当用户定义复制构造函数时构造函数的行为

时间:2014-11-06 18:27:11

标签: c++

我试图理解复制构造函数,请理解它是如何工作的。

案例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 2Case 4中收到错误消息?这是因为我创建了用户定义的复制构造函数?如果原因是用户定义的复制构造函数,甚至编译器提供了默认的复制构造函数。像内部fruit(fruit &)那样即使这样,编译器提供的程序也可以使用复制构造函数。为什么它不会在Case 1Case 3

中引发错误

我理解当用户定义复制构造函数时,所有构造函数都被=阻止。 =只能调用复制构造函数。但是必须有一个类的复制构造函数可以由用户或编译器。如果它是由编译器提供的,那么它也必须引发错误。但这不是为什么?

2 个答案:

答案 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)