C++调用空指针对象的成员函数——静态绑定与动态绑定
2016-08-06 13:31
423 查看
最近代码中看到调用空指针对象的成员函数的写法,联想起上次碰到的问题:
C++类的成员函数存储方式(是否属于类的对象)
两者的本质是一样的,上次只是简单地讨论了下,这次从编译器的角度,来谈一谈这个知识点。
一个简单的例子:
该语句的意图是:调用对象somenull的foo成员函数。
这句话在Java或Python等动态绑定的语言之中,编译器生成的代码大概是:
找到对象somenull的foo成员函数,调用它。(注意,这里的找到是程序运行的时候才找的,这也是所谓动态绑定的含义:运行时才绑定这个函数名与其对应的实际代码。有时也叫迟绑定。)
而对于C++,为了保证程序的运行时效率,C++的设计者认为凡是编译时能确定的事情,就不要拖到运行时再查找了。所以C++的编译器看到这句话会这么干:
1、查找somenull的类型B,发现该类型有一个非虚的成员函数叫foo。
2、找到了,在这里生成一个函数调用,直接调B::foo(somenull)。
所以到了运行时,由于foo()函数里面并没有任何需要解引用somenull指针的代码,所以真实情况下也不会引发segment fault。这里对成员函数的解析,和查找其对应的代码的工作都是在编译阶段完成而非运行时完成的,这就是所谓的静态绑定,也叫早绑定。
因此上述代码能够正确运行的真正原因是:对于非虚成员函数,C++这门语言是静态绑定的。
在C++中,每个对象都有一个指向自己的this指针,它的作用主要就是用来区分不同的对象,这样你就可以根据它来访问不同的对象的成员变量。
编译器编译后的成员函数的第一个参数是this指针,通过this指针引用数据成员及调用其它成员函数。
实际上相当于:
hello函数并没有使用类中的任何成员变量,所以,它也就不会用到this指针,即使此时的this指针是NULL,也不妨碍我们使用hello函数,然而,如果你调用pmy->print(),那么将会报空指针错误,因为这个函数试图用this指针访问成员变量i,而此时this为NULL。
需要注意的是,虚函数一般是动态绑定的~
C++类的成员函数存储方式(是否属于类的对象)
两者的本质是一样的,上次只是简单地讨论了下,这次从编译器的角度,来谈一谈这个知识点。
一个简单的例子:
class MyClass { public: int i; void hello() { printf("hello\n"); } void print() { printf("%d\n", i); } }; void main() { MyClass* pmy = NULL; pmy->hello(); }
“静态绑定”和“动态绑定”的区别
以下面的语句为例:somenull->foo();
该语句的意图是:调用对象somenull的foo成员函数。
这句话在Java或Python等动态绑定的语言之中,编译器生成的代码大概是:
找到对象somenull的foo成员函数,调用它。(注意,这里的找到是程序运行的时候才找的,这也是所谓动态绑定的含义:运行时才绑定这个函数名与其对应的实际代码。有时也叫迟绑定。)
而对于C++,为了保证程序的运行时效率,C++的设计者认为凡是编译时能确定的事情,就不要拖到运行时再查找了。所以C++的编译器看到这句话会这么干:
1、查找somenull的类型B,发现该类型有一个非虚的成员函数叫foo。
2、找到了,在这里生成一个函数调用,直接调B::foo(somenull)。
所以到了运行时,由于foo()函数里面并没有任何需要解引用somenull指针的代码,所以真实情况下也不会引发segment fault。这里对成员函数的解析,和查找其对应的代码的工作都是在编译阶段完成而非运行时完成的,这就是所谓的静态绑定,也叫早绑定。
因此上述代码能够正确运行的真正原因是:对于非虚成员函数,C++这门语言是静态绑定的。
在C++中,每个对象都有一个指向自己的this指针,它的作用主要就是用来区分不同的对象,这样你就可以根据它来访问不同的对象的成员变量。
编译器编译后的成员函数的第一个参数是this指针,通过this指针引用数据成员及调用其它成员函数。
MyClass* pmy = NULL; pmy->hello();
实际上相当于:
MyClass::hello(NULL);
hello函数并没有使用类中的任何成员变量,所以,它也就不会用到this指针,即使此时的this指针是NULL,也不妨碍我们使用hello函数,然而,如果你调用pmy->print(),那么将会报空指针错误,因为这个函数试图用this指针访问成员变量i,而此时this为NULL。
需要注意的是,虚函数一般是动态绑定的~
相关文章推荐
- C++调用空指针对象的成员函数成功的理解
- C++成员函数指针及C++函数对象
- C++中的成员函数调用原理及this指针的传递方式
- c++指针深入全面总结--包括对象数据成员和成员函数的指针
- C++中当对象指针为空时,虚函数和非虚函数的调用情况
- 使用纯C函数指针调用C++的类成员函数
- [疑问]C/C++中为什么在类外利用多态基类指向派生类指针可以调用类的私有成员函数?
- c++对象内存布局与c++成员函数指针
- [转]浅谈C++指针直接调用类成员函数
- 使用纯C函数指针调用C++的类成员函…
- 浅析C++中的this指针 通过空指针(NULL)可以正确调用一些类的成员函数?
- C++对象布局及多态之虚成员函数如何调用
- 当指针并没有指向实际的对象时,能否调用对象的成员函数
- 转: C++指针直接调用类成员函数探讨
- C++指针直接调用类成员函数探讨
- C++ - 对象模型之 成员函数调用
- 关于 接口与对象指针对成员函数的调用时的汇编执行行为分析
- 关于在C++内用指针调用类的成员函数
- C++成员函数指针的另类调用方法
- C++成员函数指针定义和调用