读书人

满载的细节

发布时间: 2012-10-18 13:46:56 作者: rapoo

重载的细节

C/C++ code
#include <iostream>using namespace std;class A{    int b;    public:    A(int m=0):b(m){cout<<"one arg constructor"<<endl;}    A(const A& another){        cout<<"const copy constuctor is called"<<endl;        b=another.getvalue();    }    A(A& another){        cout<<"not const copy constuctor is called"<<endl;        b=another.getvalue();    }    ~A(){cout<<this->getvalue()<<" destructor is called"<<endl;}    int getvalue()const{return b;}    A operator +(A& another){        cout<<"using  +"<<endl;        return A(b+another.getvalue());    }    A& operator =(const A& another){        cout<<"using ="<<endl;        b=another.getvalue();        return *this;    }    operator int(){        cout<<"A to int is called."<<endl;        return getvalue();    }    };int main(int argc, char *argv[]){    int m=3;    A a=m,b=m+1;    A d=a+b;    cout<<"-------2-------"<<endl;    d=a+b;    cout<<"---------------"<<endl;    return 0;}




问题如下:

对于第34行与36行两者区别是一个是创建,一个是已知。

为什么创建的时候,a+b结果为一对象时,没有调用赋值呢?或者调用拷贝构造?


同时也没有产生临时变量呢?

而后面一样,也没使用拷贝构造或者使用类型转换?



请详细说明,细节说得越细越好!!!!!

[解决办法]
第34行:
首先调用对加号的重载函数,输出“using +”,但在此函数内部的返回语句(第19行)调用了第6行的构造函数,此函数输出“one arg constructor”,最后创建对象b,由于没有提供参数,会调用编译器提供的不带参数的构造函数,而不是第6行的带默认参数的构造函数,所以什么也不输出。最后再把 a+b 的结果赋给 d,调用对赋值的重载函数,但是这里要注意的是你的那个重载返回的是一个引用,所以编译器并不是调用的你的重载函数,而是调用编译器提供的空的重载函数,所以啥也不输出。第34行执行结束
[解决办法]
zhcosin的回答大体上正确,几个地方我再说一下我的分析。

当一个class具有一个copy-ctor,compiler就会对一个函数调用进行copy-ctor策略转化。这导致下面这个方法会被转化:

A operator+(A& another)

=>

void operator+(A& result, A&another )

对该方法的调用也进行转化

a.operator+(b)

=>

A temp;
a.operator+(temp, b);

temp将不会被调用default-ctor,因为这是在compiler-time转化期进行的,而不是程序设计期:)在上面的程序中,

A d = a+b;

进一步被优化成

a.operator(d, b);

这解释了为什么这个期间,没有任何的copy-ctor被调用。在这个方法内部

return A(...)

因此变成了

return;

结果直接放到了d中。从而不会引起temp,也就是d的析构。

后面

d = a+b;

中,a+b仍然按照上面的进行调用,但temp因为不会被按照copy-ctory策略进行优化给一个新建立的object(就像上面的d)。因此会在方法完成后析构temp。


读书人网 >C++

热点推荐