2017-03-09 60 views
0

这是一个相对简单的代码,它包含一个重载赋值运算符和一个乘法运算符。我已经为两个操作符返回了一个对象的值。什么是我的问题是,当我使用赋值运算符时,复制构造函数总是被调用,而乘法运算符则永远不会调用复制构造函数。运算符在不同运算符重载时调用复制构造函数

#include<iostream> 
using namespace std; 
class foo { 
public: 
    int x; 
    foo() {x=1;} 
    foo(int a){x=a;} 
    foo(const foo &p){ 
    cout<<"CC:\tCopying from: "<<p.x<<'\t'<<&p<<"\tTo: "<<this<<endl; 
    } 
    foo operator=(const foo &r){ 
     cout<<"Assgn:\t"<<"Assigning from: "<<r.x<<'\t'<<&r 
      <<"\tTo: "<<this->x<<'\t'<<this<<endl; 
     return *this; 
    } 
    foo operator*(const foo &r){ 
     cout<<"Product:\t"<<"Multiplying from: "<<r.x<<'\t'<<&r 
      <<"\tTo: "<<this->x<<'\t'<<this<<endl; 
     return foo(x*r.x); 
    } 
}; 

int main() { 
    foo x(1),y(2); 
    foo z=x=y; 
    foo a=x*y; 
    x.x=1; y.x=2; 
    x*y*z; 
    x=y=z; 
    cout<<"X: "<<&x<<endl<<"Y: "<<&y<<endl<<"Z: "<<&z<<endl; 
} 

下面是输出:

Assgn: Assigning from: 2 0x7fff2cddbf70 To: 1 0x7fff2cddbf78 
CC: Copying from: 1 0x7fff2cddbf78 To: 0x7fff2cddbf68 
Product: Multiplying from: 2 0x7fff2cddbf70 To: 1 0x7fff2cddbf78 
Product: Multiplying from: 2 0x7fff2cddbf70 To: 1 0x7fff2cddbf78 
Product: Multiplying from: 7618584 0x7fff2cddbf68 To: 2 0x7fff2cddbf58 
Assgn: Assigning from: 7618584 0x7fff2cddbf68 To: 2 0x7fff2cddbf70 
CC: Copying from: 2 0x7fff2cddbf70 To: 0x7fff2cddbf48 
Assgn: Assigning from: 3 0x7fff2cddbf48 To: 1 0x7fff2cddbf78 
CC: Copying from: 1 0x7fff2cddbf78 To: 0x7fff2cddbf40 
X: 0x7fff2cddbf78 
Y: 0x7fff2cddbf70 
Z: 0x7fff2cddbf68 

基本的事情是,当乘法运算符的使用(甚至当我有类似foo“声明从来没有被称为拷贝构造函数A = X * Y')。但是在返回'a = b'的值时,复制构造函数被调用的是

我知道,编译器优化,使输出的一些变化,这就是为什么不调用CC当我宣布样z = x = yz = x * y的变量。但是,为什么当CC返回x = y时,为什么它可以直接计算z,就像z = x * y那样?这有什么特别的原因吗?类似的,赋值运算符的处理方式不同,或者因为我在赋值运算符中返回*this,它与乘法运算符中的情况不同,在该运算符中,我返回一个临时变量(这应该不太可能,因为ASFAIK,编译器无法区分变量本地和全球范围)。

回答

0

我试图达到答案时的一个假设是错误的。

我试过同样的事情,只是稍微改变了赋值操作符的定义,所以我首先将该值存储在本地变量中,然后将其返回。在这种情况下,没有复制构造函数被调用。

这意味着编译器可以区别不同范围的变量。由于我在问题中发布的代码返回非本地变量,因此调用了copy-constructor。

我猜测当我从类之外的其他函数调用赋值运算符时,会发生同样的事情(即调用CC)。更好的是,看到CC在同一个类的不同成员函数中调用时会发生什么(尽管它可能是相同的)会很有趣。