MyClass::Foo() 其实是一个全局函数, 在符号表中的名字是 "_ZN7MyClass2FooEv". 所以调用时并不需要通过对象指针. 不过在调用这个函数时,会传递对象指针进去.
函数的定义:
.globl _ZN7MyClass3FooEv
.type _ZN7MyClass3FooEv, @function
_ZN7MyClass3FooEv:
.LFB1442:
pushl %ebp
.LCFI4:
movl %esp, %ebp
.LCFI5:
subl $8, %esp
.LCFI6:
subl $8, %esp
pushl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
subl $12, %esp
pushl $.LC0
pushl $_ZSt4cout
.LCFI7:
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
addl $20, %esp
pushl %eax
.LCFI8:
call _ZNSolsEPFRSoS_E
addl $16, %esp
leave
ret
函数的调用:
ptr = NULL;
ptr->Foo();
return 0;
对应的汇编
movl $0, -4(%ebp) ;; ptr = NULL;
subl $12, %esp ;; 通过堆栈进行参数传递,传入ptr. 不过Foo()没有用到它.
pushl -4(%ebp) ;;
call _ZN7MyClass3FooEv ;; ptr->Foo()
addl $16, %esp
movl $0, %eax ;; return 0
leave
ret
通过上面的分析,我们明白了为什么这个让人迷惑的语句可以通过编译和运行了.
如果Foo()访问对象的成员,那么肯定是会出错的. 因为Foo()需要使用传入的ptr,而ptr的值是NULL.
比如
void Foo()
{
cout
- 顶
- 0
- 踩
- 0