下面是对象的汇编码:

_main    PROC

; 14   : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 24                    ; 00000018H

; 15   :     X x1;//先定义对象x1
; 16   :     X x2 = x1;//将x1拷贝给x2

    mov    eax, DWORD PTR _x1$[ebp];将x1中首地址的内容写入eax,即将x1中的成员变量值i写入eax
    mov    DWORD PTR _x2$[ebp], eax;将eax的值写入x2的首地址处,即将eax的值写入x2的成员变量i
    mov    ecx, DWORD PTR _x1$[ebp+4];将偏移x1首地址4byte处的内存里面的内容写入ecx,即将x1中成员变量j的值写入ecx
    mov    DWORD PTR _x2$[ebp+4], ecx;将ecx的值写入偏移x2首地址4byte处的内存,即将ecx的值写入x2中成员变量j
    mov    edx, DWORD PTR _x1$[ebp+8];将偏移x1首地址8byte处(这里是x1成员对象y的首地址)的内存值写入edx,即将x1中成员对象y中的成员变量i值写入edx
    mov    DWORD PTR _x2$[ebp+8], edx;将edx的值写入偏移x2首地址8byte处(这里是x2成员对象y的首地址)的内存里面,即将edx的值写入x2中成员对象y的成员变量i里面

  从汇编吗可以看出,编译器在这种情况下任然只是提供无用的默认拷贝构造函数,即没有显示的函数调用,只是用寄存器和内存之间的通信完成拷贝过程

  综合上面的分析,可以看到:

  对于一个类,如果它没有显示定义拷贝构造函数,编译器并不总是提供非无用的默认拷贝构造函数,除非:

  1、该类包含虚函数成员函数(包括继承自虚基类或者继承的基类中有虚函数成员),这时编译器提供为该类提供非无用的默认拷贝构造函数

  2、该类继承自一个基类,而基类含有自定义的拷贝函数,这时编译器为该类提供非无用的默认拷贝构造函数。(如果基类本身没有定义拷贝构造函数,但是编译器会为基类提供一个非无用的默认拷贝构造函数,也属于这种情况。也是说,基类只要含有一个非无用的拷贝构造函数行,不管这个非无用的拷贝构造函数是自定义的,还是编译器提供的)

  3、该类包含一个成员对象,而该成员对象有自定的拷贝构造函数,这时编译器为该类提供非无用的默认拷贝构造函数。(如果成员对象本身没有定义拷贝构造函数,但是编译器会为成员对象提供一个非无用的默认拷贝构造函数,也属于这种情况。也是说,成员对象只要包含一个非无用的拷贝构造函数行,不管这个非无用的拷贝构造函数时自定义的,还是编译器提供的。这中情况和上一种类似).

  并且,如果一个类自定义了一个拷贝构造函数,编译器只是负责调用,不会额外提供任何拷贝过程;而对于编译器提供的默认拷贝函数,不管是无用的,还是非无用的,都仅仅只是位拷贝(即浅拷贝)。