当前位置:首页 > > 充电吧
[导读]        《深度探索C++对象模型》一书第二章关于编译器构建或扩展构造函数的结尾指出,对于我们C++新手有两个常见的误解:1,任何没有定义default constructor的class,编译

        《深度探索C++对象模型》一书第二章关于编译器构建或扩展构造函数的结尾指出,对于我们C++新手有两个常见的误解:

1,任何没有定义default constructor的class,编译器都会自动替程序员合成一个出来;

2,编译器合成出来的default constructor会默认对class的数据成员进行初始化。

然而,事实上并非如此,但是有很多地方我们确实见到过这种说法呀,到底什么时候编译器会为我们做这个事情呢?书中总结了四种情况下,编译器会为了需要合成或者扩展构造函数:

1,class中有data member是某class的object,并且此object所属的class有default constructor;

2,class继承自有default constructor的base class;

3,class中定义了virtual function或者继承有virtual function,编译器需要为此类object初始化virtual function table;

4,class以virtual方式继承base class。

        第二种情况是最简单的,如果class没有定义某class类型的object data member,同时没有virtual function和virtual base class,则如果此class没有定义默认构造函数,有两种情况发生:1,如果定义有其他带参数构造函数,则创建对象时必须传入参数,而不管其继承的base class是否有默认构造函数,否则会报找不到构造函数的错误;2,如果没有定义任何构造函数,并且其继承的base class有默认构造函数,则编译器会为其合成默认构造函数,但是不会对其基本数据类型的数据成员初始化。


class BaseA{
       
          
};
class ChildB:public BaseA{
public:
};

int main()
{
    ChildB child;
    return 0;
}
class BaseA{
public:
BaseA() {}
};
class ChildB:public BaseA{
public:
};

int main()
{
    ChildB child;
    return 0;
}

编译结果:


##################################

.file "testdef.cpp"

                                                                                                                                                                                                                                                         


                                                                                                                                                                                                                                                                              

         
                     
                                
               
      
               
           
                       
                   
                
                        
               
                    
                    

                








                   
      
                  
    
             
      
                                       
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
               
                    
                
                    
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
                    
                                 
                     
                                   
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits .file"testinh.cpp"
.section .text._ZN5BaseAC2Ev,"axG",@progbits,_ZN5BaseAC5Ev,comdat
.align 2
.weak _ZN5BaseAC2Ev
.type _ZN5BaseAC2Ev, @function
_ZN5BaseAC2Ev:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size _ZN5BaseAC2Ev, .-_ZN5BaseAC2Ev
.section .text._ZN6ChildBC2Ev,"axG",@progbits,_ZN6ChildBC5Ev,comdat
.align 2
.weak _ZN6ChildBC2Ev
.type _ZN6ChildBC2Ev, @function
_ZN6ChildBC2Ev:
.LFB5:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rdi
call _ZN5BaseAC2Ev
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE5:
.size _ZN6ChildBC2Ev, .-_ZN6ChildBC2Ev
.text
.globl main
.type main, @function
main:
.LFB3:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
leaq -1(%rbp), %rax
movq %rax, %rdi
call _ZN6ChildBC1Ev
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE3:
.size main, .-main
.weak _ZN5BaseAC1Ev
.set _ZN5BaseAC1Ev,_ZN5BaseAC2Ev
.weak _ZN6ChildBC1Ev
.set _ZN6ChildBC1Ev,_ZN6ChildBC2Ev
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits


由此对比,Child Class的默认构造函数由编译器自动构造出来了。

        针对第一种情况,如果class定义了某个object成员,此object所属类有默认构造函数,则:

        1,如果class中无构造函数,则编译器将自动合成默认构造函数,并初始化object成员


class BaseA{
public:
BaseA() {}
};

class ChildB{
public:
           
BaseA basea;
};


int main()
{
ChildB child;
return 0;
}
class BaseA{
public:
BaseA() {}
};

class ChildB{
public:
ChildB() {}
BaseA basea;
};


int main()
{
ChildB child;
return 0;
}


编译结果:


.file "testdef.cpp"
.section .text._ZN5BaseAC2Ev,"axG",@progbits,_ZN5BaseAC5Ev,comdat
.align 2
.weak _ZN5BaseAC2Ev
.type _ZN5BaseAC2Ev, @function
_ZN5BaseAC2Ev:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size _ZN5BaseAC2Ev, .-_ZN5BaseAC2Ev
.section .text._ZN6ChildBC2Ev,"axG",@progbits,_ZN6ChildBC5Ev,comdat
.align 2
.weak _ZN6ChildBC2Ev
.type _ZN6ChildBC2Ev, @function
_ZN6ChildBC2Ev:
.LFB5:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rdi
call _ZN5BaseAC1Ev
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE5:
.size _ZN6ChildBC2Ev, .-_ZN6ChildBC2Ev
.text
.globl main
.type main, @function
main:
.LFB3:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
leaq -1(%rbp), %rax
movq %rax, %rdi
call _ZN6ChildBC1Ev
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE3:
.size main, .-main
.weak _ZN5BaseAC1Ev
.set _ZN5BaseAC1Ev,_ZN5BaseAC2Ev
.weak _ZN6ChildBC1Ev
.set _ZN6ChildBC1Ev,_ZN6ChildBC2Ev
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits .file "testinh.cpp"
.section .text._ZN5BaseAC2Ev,"axG",@progbits,_ZN5BaseAC5Ev,comdat
.align 2
.weak _ZN5BaseAC2Ev
.type _ZN5BaseAC2Ev, @function
_ZN5BaseAC2Ev:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size _ZN5BaseAC2Ev, .-_ZN5BaseAC2Ev
.section .text._ZN6ChildBC2Ev,"axG",@progbits,_ZN6ChildBC5Ev,comdat
.align 2
.weak _ZN6ChildBC2Ev
.type _ZN6ChildBC2Ev, @function
_ZN6ChildBC2Ev:
.LFB4:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rdi
call _ZN5BaseAC1Ev
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE4:
.size _ZN6ChildBC2Ev, .-_ZN6ChildBC2Ev
.text
.globl main
.type main, @function
main:
.LFB6:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
leaq -1(%rbp), %rax
movq %rax, %rdi
call _ZN6ChildBC1Ev
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE6:
.size main, .-main
.weak _ZN5BaseAC1Ev
.set _ZN5BaseAC1Ev,_ZN5BaseAC2Ev
.weak _ZN6ChildBC1Ev
.set _ZN6ChildBC1Ev,_ZN6ChildBC2Ev
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits

        2,若class中提供了任意构造函数,但是未对object成员初始化,则编译器将在构造函数中插入object成员的初始化操作,即扩展已有的构造函数


class BaseA{
public:
BaseA() {}
};

class ChildB{
public:
ChildB() {}
BaseA basea;
};


int main()
{
ChildB child;
return 0;
}
class BaseA{
public:
BaseA() {}
};

class ChildB{
public:
ChildB():basea() {}
BaseA basea;
};


int main()
{
ChildB child;
return 0;
}

编译结果


.file "testinh.cpp"
.section .text._ZN5BaseAC2Ev,"axG",@progbits,_ZN5BaseAC5Ev,comdat
.align 2
.weak _ZN5BaseAC2Ev
.type _ZN5BaseAC2Ev, @function
_ZN5BaseAC2Ev:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size _ZN5BaseAC2Ev, .-_ZN5BaseAC2Ev
.section .text._ZN6ChildBC2Ev,"axG",@progbits,_ZN6ChildBC5Ev,comdat
.align 2
.weak _ZN6ChildBC2Ev
.type _ZN6ChildBC2Ev, @function
_ZN6ChildBC2Ev:
.LFB4:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rdi
call _ZN5BaseAC1Ev
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE4:
.size _ZN6ChildBC2Ev, .-_ZN6ChildBC2Ev
.text
.globl main
.type main, @function
main:
.LFB6:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
leaq -1(%rbp), %rax
movq %rax, %rdi
call _ZN6ChildBC1Ev
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE6:
.size main, .-main
.weak _ZN5BaseAC1Ev
.set _ZN5BaseAC1Ev,_ZN5BaseAC2Ev
.weak _ZN6ChildBC1Ev
.set _ZN6ChildBC1Ev,_ZN6ChildBC2Ev
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits .file "testdef.cpp"
.section .text._ZN5BaseAC2Ev,"axG",@progbits,_ZN5BaseAC5Ev,comdat
.align 2
.weak _ZN5BaseAC2Ev
.type _ZN5BaseAC2Ev, @function
_ZN5BaseAC2Ev:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size _ZN5BaseAC2Ev, .-_ZN5BaseAC2Ev
.section .text._ZN6ChildBC2Ev,"axG",@progbits,_ZN6ChildBC5Ev,comdat
.align 2
.weak _ZN6ChildBC2Ev
.type _ZN6ChildBC2Ev, @function
_ZN6ChildBC2Ev:
.LFB4:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rdi
call _ZN5BaseAC1Ev
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE4:
.size _ZN6ChildBC2Ev, .-_ZN6ChildBC2Ev
.text
.globl main
.type main, @function
main:
.LFB6:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
leaq -1(%rbp), %rax
movq %rax, %rdi
call _ZN6ChildBC1Ev
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE6:
.size main, .-main
.weak _ZN5BaseAC1Ev
.set _ZN5BaseAC1Ev,_ZN5BaseAC2Ev
.weak _ZN6ChildBC1Ev
.set _ZN6ChildBC1Ev,_ZN6ChildBC2Ev
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits         第三种情况,class中定义有virtual function或者继承链中有类定义了virtual function,编译器需要为class类型的对象创建vtl和vptr,因此编译器将自动合成默认构造函数


class ChildB{
public:
           
virtual void func() {}
};


int main()
{
ChildB child;
return 0;
}
class ChildB{
public:
ChildB() {}
virtual void func() {}
};


int main()
{
ChildB child;
return 0;
}

编译结果


.file "testdef.cpp"
.section .text._ZN6ChildB4funcEv,"axG",@progbits,_ZN6ChildB4funcEv,comdat
.align 2
.weak _ZN6ChildB4funcEv
.type _ZN6ChildB4funcEv, @function
_ZN6ChildB4funcEv:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
                    
                             
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size _ZN6ChildB4funcEv, .-_ZN6ChildB4funcEv
.section .text._ZN6ChildBC2Ev,"axG",@progbits,_ZN6ChildBC5Ev,comdat
.align 2
.weak _ZN6ChildBC2Ev
.type _ZN6ChildBC2Ev, @function
_ZN6ChildBC2Ev:
.LFB3:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq $_ZTV6ChildB+16, (%rax)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE3:
.size _ZN6ChildBC2Ev, .-_ZN6ChildBC2Ev
.text
.globl main
.type main, @function
main:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
leaq -16(%rbp), %rax
movq %rax, %rdi
call _ZN6ChildBC1Ev
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size main, .-main
.weak _ZTV6ChildB
.section .rodata._ZTV6ChildB,"aG",@progbits,_ZTV6ChildB,comdat
.align 16
.type _ZTV6ChildB, @object
.size _ZTV6ChildB, 24
_ZTV6ChildB:
.quad 0
.quad _ZTI6ChildB
.quad _ZN6ChildB4funcEv
.weak _ZTS6ChildB
.section .rodata._ZTS6ChildB,"aG",@progbits,_ZTS6ChildB,comdat
.type _ZTS6ChildB, @object
.size _ZTS6ChildB, 8
_ZTS6ChildB:
.string "6ChildB"
.weak _ZTI6ChildB
.section .rodata._ZTI6ChildB,"aG",@progbits,_ZTI6ChildB,comdat
.align 16
.type _ZTI6ChildB, @object
.size _ZTI6ChildB, 16
_ZTI6ChildB:
.quad _ZTVN10__cxxabiv117__class_type_infoE+16
.quad _ZTS6ChildB
.weak _ZN6ChildBC1Ev
.set _ZN6ChildBC1Ev,_ZN6ChildBC2Ev
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits .file "testinh.cpp"
.section .text._ZN6ChildBC2Ev,"axG",@progbits,_ZN6ChildBC5Ev,comdat
.align 2
.weak _ZN6ChildBC2Ev
.type _ZN6ChildBC2Ev, @function
_ZN6ChildBC2Ev:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq $_ZTV6ChildB+16, (%rax)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size _ZN6ChildBC2Ev, .-_ZN6ChildBC2Ev
.section .text._ZN6ChildB4funcEv,"axG",@progbits,_ZN6ChildB4funcEv,comdat
.align 2
.weak _ZN6ChildB4funcEv
.type _ZN6ChildB4funcEv, @function
_ZN6ChildB4funcEv:
.LFB3:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
                    
                             
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE3:
.size _ZN6ChildB4funcEv, .-_ZN6ChildB4funcEv
.text
.globl main
.type main, @function
main:
.LFB4:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
leaq -16(%rbp), %rax
movq %rax, %rdi
call _ZN6ChildBC1Ev
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE4:
.size main, .-main
.weak _ZTV6ChildB
.section .rodata._ZTV6ChildB,"aG",@progbits,_ZTV6ChildB,comdat
.align 16
.type _ZTV6ChildB, @object
.size _ZTV6ChildB, 24
_ZTV6ChildB:
.quad 0
.quad _ZTI6ChildB
.quad _ZN6ChildB4funcEv
.weak _ZTS6ChildB
.section .rodata._ZTS6ChildB,"aG",@progbits,_ZTS6ChildB,comdat
.type _ZTS6ChildB, @object
.size _ZTS6ChildB, 8
_ZTS6ChildB:
.string "6ChildB"
.weak _ZTI6ChildB
.section .rodata._ZTI6ChildB,"aG",@progbits,_ZTI6ChildB,comdat
.align 16
.type _ZTI6ChildB, @object
.size _ZTI6ChildB, 16
_ZTI6ChildB:
.quad _ZTVN10__cxxabiv117__class_type_infoE+16
.quad _ZTS6ChildB
.weak _ZN6ChildBC1Ev
.set _ZN6ChildBC1Ev,_ZN6ChildBC2Ev
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits         第四种情况,class以virtual方式继承,或者其继承链中有virtual方式的继承,编译器为此class和base class均自动合成默认构造函数


class BaseA{
};
class ChildB:public BaseA{
};


int main()
{
ChildB child;
return 0;
}
class BaseA{
};
class ChildB: virtual public BaseA{
};


int main()
{
ChildB child;
return 0;
}

编译结果


#############################################
.file "testinh.cpp"
                                                                  
         
                    
                               
              
      
               
           
                       
                   
                
                        
                    
          
                  
    
             
      
                                     
                                                                    
         
                     
                                
               
      
               
           
                       
                   
                
                        
               
                    
                    
                
                   
                           
                    
                  
      
                  
    
             
      
                                       
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
               
                     
                
                    
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
                  
                                                               
          
                           
                      
            
        
        
                  
                  
                                                               
         
                           
                     
            
                     
                  
                                                               
                           
                     
            
                  
                  
                                                               
          
                           
                      
            
                                                   
                  
        
        
                 
            
                 
                                                             
                          
                    
           
                 
                 
                                                             
          
                          
                     
           
                                               
                 
                    
                                 
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits .file "testdef.cpp"
.section .text._ZN5BaseAC2Ev,"axG",@progbits,_ZN5BaseAC5Ev,comdat
.align 2
.weak _ZN5BaseAC2Ev
.type _ZN5BaseAC2Ev, @function
_ZN5BaseAC2Ev:
.LFB3:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE3:
.size _ZN5BaseAC2Ev, .-_ZN5BaseAC2Ev
.section .text._ZN6ChildBC1Ev,"axG",@progbits,_ZN6ChildBC1Ev,comdat
.align 2
.weak _ZN6ChildBC1Ev
.type _ZN6ChildBC1Ev, @function
_ZN6ChildBC1Ev:
.LFB6:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rdi
call _ZN5BaseAC2Ev
movl $_ZTV6ChildB+24, %edx
movq -8(%rbp), %rax
movq %rdx, (%rax)
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE6:
.size _ZN6ChildBC1Ev, .-_ZN6ChildBC1Ev
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
leaq -16(%rbp), %rax
movq %rax, %rdi
call _ZN6ChildBC1Ev
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.weak _ZTV6ChildB
.section .rodata._ZTV6ChildB,"aG",@progbits,_ZTV6ChildB,comdat
.align 16
.type _ZTV6ChildB, @object
.size _ZTV6ChildB, 24
_ZTV6ChildB:
.quad 0
.quad 0
.quad _ZTI6ChildB
.weak _ZTT6ChildB
.section .rodata._ZTT6ChildB,"aG",@progbits,_ZTV6ChildB,comdat
.align 8
.type _ZTT6ChildB, @object
.size _ZTT6ChildB, 8
_ZTT6ChildB:
.quad _ZTV6ChildB+24
.weak _ZTS6ChildB
.section .rodata._ZTS6ChildB,"aG",@progbits,_ZTS6ChildB,comdat
.type _ZTS6ChildB, @object
.size _ZTS6ChildB, 8
_ZTS6ChildB:
.string "6ChildB"
.weak _ZTI6ChildB
.section .rodata._ZTI6ChildB,"aG",@progbits,_ZTI6ChildB,comdat
.align 32
.type _ZTI6ChildB, @object
.size _ZTI6ChildB, 40
_ZTI6ChildB:
.quad _ZTVN10__cxxabiv121__vmi_class_type_infoE+16
.quad _ZTS6ChildB
.long 0
.long 1
.quad _ZTI5BaseA
.quad -6141
.weak _ZTS5BaseA
.section .rodata._ZTS5BaseA,"aG",@progbits,_ZTS5BaseA,comdat
.type _ZTS5BaseA, @object
.size _ZTS5BaseA, 7
_ZTS5BaseA:
.string "5BaseA"
.weak _ZTI5BaseA
.section .rodata._ZTI5BaseA,"aG",@progbits,_ZTI5BaseA,comdat
.align 16
.type _ZTI5BaseA, @object
.size _ZTI5BaseA, 16
_ZTI5BaseA:
.quad _ZTVN10__cxxabiv117__class_type_infoE+16
.quad _ZTS5BaseA
.weak _ZN5BaseAC1Ev
.set _ZN5BaseAC1Ev,_ZN5BaseAC2Ev
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits

        但是对于上述说的第一种误解,我是没有真正理解的,如果没有构造函数,编译器也不自动合成,对象是如何建立的?


#includeusing namespace std;

class NoDef{
public:
int k;
void print() { cout << "k is " << k << endl;}
};

int main()
{
NoDef def;
def.print();

def.k = 2;
def.print();

def.k = 199566;
def.print();

return 0;
}

由于上方的代码可以执行,那么是否说明def对象创建了?如果为NoDef添加了默认构造函数,从编译结果看,main函数中明显调用了构造函数。理解还是不到位,继续找资料学习。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭