强制转换符号重载的问题

来源:互联网 发布:iea数据 编辑:程序博客网 时间:2024/06/05 18:33

看了转换操作符的文章,如作者所述,果然有如下问题。

class convertClassC{    int data;public:    convertClassC()    {        data = 0;    }        /*    convertClassC(convertClassC &object)    {        data = object.data;       // printf("the copy constructor\n");    }    */    void dataSet(double f)    {        data = f;    }    ~convertClassC()    {    }};class convertClassD{    convertClassC objectC;public:    convertClassD():objectC()    {        objectC.dataSet(1);    }    operator convertClassC()    {       // printf("cast to convertClassA\n");        return this->objectC;    }    ~convertClassD()    {    }};int convertClass(){    convertClassC c;    convertClassD d;c = (convertClassC)d;return 1;}

这个可以运行。


但是如果增加convertClassC的拷贝构造函数,即复原convertClassC类中的注释部分,那么就无法运行,除非改变强制转换的方式,即改成引用转换。



 operator convertClassC&()    {       // printf("cast to convertClassA\n");        return this->objectC;    }

不得其解。


看其汇编代码发现强制转换分为两个步骤,在有拷贝构造函数的情况下。

009364E8  lea         ecx,[ebp-20h]  009364EB  call        convertClassD::operator convertClassC & (93119Fh)  009364F0  push        eax  009364F1  lea         ecx,[ebp-0F8h]  009364F7  call        convertClassC::convertClassC (9314B5h)  009364FC  mov         dword ptr [ebp-100h],eax  00936502  mov         eax,dword ptr [ebp-100h]  00936508  mov         ecx,dword ptr [eax]  0093650A  mov         dword ptr [ebp-14h],ecx  

其中

009364EB call convertClassD::operator


这个调用其实什么也没做,只是将B的对象的地址保存在ecx寄存器中。

然后拷贝构造一个新对象后,用新对象来完成赋值操作。


如果没有自定义拷贝构造,那么汇编代码如下

c = (convertClassC)d;00A464D8  lea         eax,[ebp-0F8h]  00A464DE  push        eax  00A464DF  lea         ecx,[ebp-20h]  00A464E2  call        convertClassD::operator convertClassC (0A4123Fh)  00A464E7  mov         byte ptr [ebp-4],2  00A464EB  mov         ecx,dword ptr [ebp-0F8h]  00A464F1  mov         dword ptr [ebp-104h],ecx  00A464F7  lea         edx,[ebp-104h]  00A464FD  mov         dword ptr [ebp-10Ch],edx  00A46503  mov         eax,dword ptr [ebp-10Ch]  00A46509  mov         ecx,dword ptr [eax]  00A4650B  mov         dword ptr [ebp-14h],ecx  

00A464E2 call convertClassD::operator

其实也是仅仅只做了一个储存d的地址的事情。

另外一点是,没有再另外创建一个对象。


综上所述,在有拷贝构造的函数的情况下,那么会先根据d的数据创建一个convertClassC的对象,然后用这个对象给赋值。


没有构造函数的情况下,那么赋值的时候就直接将convertClassB对象看做C对象,然后赋值。


按照上面看,引用运算符应当是拷贝构造新对象的时候所必须的。为什么必须呢,至今没有想到很合理的解释



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 垃圾清理把相片删除了怎么办 小米电脑怎么下载软件怎么办 华为手机pin码忘了怎么办 锁屏密码忘了怎么办 抖音停止运行了怎么办? 华为手机右下角有个小人怎么办 华为手机程序停止运行怎么办 华为手机不支持软件搬家怎么办 红米手机没有任务键怎么办 进网许可丢了怎么办 华为稳私空间被稳蔵怎么办 华为手机安装不了软件怎么办 华为手机自动安装软件怎么办 手机在实体店买贵了怎么办 日本买的kindle坏了怎么办 华为麦芒4屏幕失灵怎么办 华为麦芒6屏幕失灵怎么办 手机为什么总显示内存不足怎么办 小米云服务满了怎么办 魅蓝s6声音小怎么办 华为畅享7s丢失怎么办 华为耳机孔坏了怎么办 苹果手机耳机插孔坏了怎么办 荣耀8听筒声音小怎么办 荣耀8听筒音量小怎么办 华为荣耀6声音小怎么办 华为荣耀v8通话声音小怎么办 华为p20没有耳机孔怎么办 华为荣耀手机耳机声音小怎么办 小米5x显示耳机怎么办 手机进水听音乐人声小怎么办 华为荣耀v8手机音量小怎么办 手机充电孔松了怎么办 华为荣耀7卡顿怎么办 华为手机话筒没声音怎么办 苹果x耳机进水了怎么办 苹果6p进水了怎么办 华为手机声音变耳机模式怎么办 手机设置成耳机模式怎么办 opop耳机一个没有声音怎么办 oppo手机上显示耳机模式怎么办