为什么NULL指针也能访问成员函数?(但不能访问成员变量)
查看更加详细的解析请参考这篇文章:http://blog.51cto.com/9291927/2148695
看一个静态绑定的例子:
1 #include <iostream>
2
3 using namespace std;
4
5 class A
6 {
7 public:
8 int a = 3;
9 void test1()
10 {
11 printf("test A\n");
12 }
13 void test2()
14 {
15 cout << a;
16 }
17 };
18
19 int main()
20 {
21 A *pA = NULL;
22 cout << pA.a; //错误:NULL指针不能访问类非static的成员变量
23 pA -> test1(); //正确:输出test A
24 pA -> test2(); //错误:NULL指针不能访问类非static的成员变量
25 return 0;
26 }
分析: 由于test是非虚函数,对于非虚成员函数,C++是静态绑定的,即在编译时就确定了,即编译器在编译的时候就知道。空对象指针不能访问非static成员变量,但可以访问成员函数( 非虚函数 ),因为数据成员要分配内存才能访问,而函数是不需要的。
解析(1):
这语句的意图是:调用对象 pA 的 test 成员函数。如果这句话在Java或Python等动态绑定的语言之中,编译器生成的代码大概是:
找到 pA 的 test 成员函数,调用它。(注意,这里的找到是程序运行的时候才找的,这也是所谓动态绑定的含义:运行时才绑定这个函数名与其对应的实际代码。有些地方也称这种机制为迟绑定,晚绑定。)
但是对于C++。为了保证程序的运行时效率,C++的设计者认为凡是编译时能确定的事情,就不要拖到运行时再查找了。所以C++的编译器看到这句话会这么干:
1:查找 pA 的类型,发现它有一个非虚的成员函数叫 test 。(编译器干的)
2:找到了,在这里生成一个函数调用,直接调A:: test ( pA )。
所以到了运行时,由于 test ()函数里面并没有任何需要解引用 pA 指针的代码,所以真实情况下也不会引发segment fault。这里对成员函数的解析,和查找其对应的代码的工作都是在编译阶段完成而非运行时完成的,这就是所谓的静态绑定,也叫早绑定。
正确理解C++的静态绑定可以理解一些特殊情况下C++的行为。
解析(2):
test函数作为非虚函数,在编译时就确定了。即使pA为null,但是已经声明了类型,就知道pA有个test函数,且test函数里没有用到成员变量,单单一个打印语句是可以运行成功的。
本题中NULL指针调用成员函数的时候成员函数中没有成员变量,如果访问此对象的成员函数,则程序崩溃,因为this指针是NULL
为什么NULL指针也能访问成员函数?(但不能访问成员变量)的更多相关文章
- 类1(this指针/const成员函数/类作用域/外部成员函数/返回this对象的函数)
假设我们要设计一个包含以下操作的 Sales_data 类: 1.一个 isbn 成员函数,用于返回对象的 book_no 成员变量 2.一个 combine 成员函数,用于将一个 Sales_dat ...
- YTU 2634: E3 继承了,成员函数却不可访问
2634: E3 继承了,成员函数却不可访问 时间限制: 1 Sec 内存限制: 128 MB 提交: 521 解决: 435 题目描述 下面的程序中,派生类Derive继承自基类Base,mai ...
- static成员函数不能调用non-static成员函数
1 一般类静态成员函数不能调用非静态成员函数 2 static成员函数可以调用构造函数吗? 答案是肯定的,由于static成员函数没有this指针,所以一般static成员函数是不能访问non-sta ...
- 父类指针指向子类内存,为什么当父类的成员函数不加virtual时,访问的还是父类的成员函数,而不是子类同名的成员函数
我认为是这样,类的成员函数都在代码区,不同的类的成员函数在代码区有自己的类名称空间限制,类的虚函数在虚函数表中,程序执行的时候,是先在虚函数表中找该成员函数,如果没有找到,就去该类在代码区的成员函数中 ...
- [Reprint]C++普通函数指针与成员函数指针实例解析
这篇文章主要介绍了C++普通函数指针与成员函数指针,很重要的知识点,需要的朋友可以参考下 C++的函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般 ...
- C++ 成员函数赋值给C 的函数指针的采坑录
最近做一个banana Pi M1+的硬解码器封装成类的时候,由于是依赖ffmpeg的,而ffmpeg是C 实现的,本来demo 都是直接用C写的,测试也没有问题,想着封装也不会有问题,至少自己对C+ ...
- this指针和const成员函数
1.this指针 1)this指针是成员函数的隐式参数,成员函数通过this指针来访问调用它自己的那个对象,成员函数对各成员的访问均通过this进行 2)当某个对象调用它的成员函数时,编译器会把这个对 ...
- C++学习之普通函数指针与成员函数指针
函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般函数的函数指针使用的比较多,而对指向类成员函数的函数指针则比较陌生.我最近也被问到了这方面的问题,心中 ...
- 类 this指针 const成员函数
C++ Primer 第07章 类 7.1.2 Sales_data类的定义如下: #ifndef SALES_DATA_H #define SALES_DATA_H #include <st ...
- 类 this指针 const成员函数 std::string isbn() const {return bookNo;}
转载:http://www.cnblogs.com/little-sjq/p/9fed5450f45316cf35f4b1c17f2f6361.html C++ Primer 第07章 类 7.1.2 ...
随机推荐
- luogu P3760 [TJOI2017]异或和
传送门 对于每个二进制位考虑有多少区间和这一位上为1 从前往后扫每个前缀和,如果当前这个前缀和某一个二进制位上为1,因为区间和由这个前缀和减去前面的前缀和得来,如果减去了这一位为0的前缀和,那么 减去 ...
- CF418D Big Problems for Organizers
传送门 题意,给一棵树,每次给两个点\(x,y\),求\(\max_{i=1}^{n}(\min(di_{x,i},di_{y,i}))\) 看std看了好久 以下是一个优秀的在线做法,\(O(nlo ...
- 2017CCPC秦皇岛 L题One-Dimensional Maze&&ZOJ3992【模拟】
链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3992 题意: 走迷宫,一个一维字符串迷宫,由'L'.'R'组成,分别 ...
- mod_wsgi 的两种模式
mod_wsgi 的两种模式 http://ssmax.net/archives/977.html http://www.cnblogs.com/yuxc/p/3555005.html mod_wsg ...
- 「About Blockchain(一)」达沃斯年会上的区块链
「About Blockchain(一)」 --达沃斯年会上的区块链 写在前面:1月23日到26日,在瑞士达沃斯召开了第48届世界经济论坛.这个新闻本没有引起我格外的关注,直到前两天张老师分享给我一篇 ...
- Your Database is downloaded and backed up on....(腾讯云的mysql被攻击)
今天发现自己的服务器被黑客攻击,自己的mysql服务器的库被删掉,并且新创了一个warning库,只有一个readme表.不知道原因,也许是自己再github上的项目暴漏了自己的密码,还要0.6比特币 ...
- Principal components analysis(PCA):主元分析
在因子分析(Factor analysis)中,介绍了一种降维概率模型,用EM算法(EM算法原理详解)估计参数.在这里讨论另外一种降维方法:主元分析法(PCA),这种算法更加直接,只需要进行特征向量的 ...
- linux内核capable源代码分析【转】
转自:https://blog.csdn.net/sanwenyublog/article/details/50856849 linux内核里对于进程的权限管理有一个很重要的函数capable,以前看 ...
- db_recovery_file_dest_size
select name,space_limit,space_used,number_of_files from v$recovery_file_dest; alter system set db_re ...
- tomcat中gzip压缩
在tomcat中压缩文件,修改server.xml文件中的配置 <Connector port="8080" protocol="HTTP/1.1" co ...