首先:为什么这边一定是这样排列的
还记得Teacher Lei说过吗?原因:子类在初始化的时候是先调用父类的构造函数!!
说明父类的成员一定是先被初始化的。
所以这边的结构必然是这样的。(这里很重要)
好了。到现在基本就把要知道的基础知识解决了。
不知道读着博客的人累了没有。。呵呵。后面的更精彩。
现在 把child对象的地址赋值给指针parent(即 parent = &child)
先来看看 parent->cVar 为什么不行?!
第一步:parent->cVar 其实是一个地址的偏移过程,现在parent的地址是200;那么cVar就代表2个偏移量;
按说电脑是可以找到202的这个地址的值。可是为什么不行呢?
第二步:在程序的编译过程中,每一个的成员函数名都被当做一个偏移量。
就像这里,pVar代表量1个偏移。cVar代表2个偏移量。
第三步:parent是Parent类型的。这个很关键。因为在编译的以后,parent已经初始化了一个最大偏移量max (这里的max为1)
第四步:结果已经很明显了。因为parent的最大偏移量max 为1。程序根本找不着偏移量为2的变量地址。
然后看看 parent->privatePrint() 为什么不行?
还是那个关键点。parent是Parent类型的,还记得上面说类在内存中的加载方式吗?parent指向的是Parent的内存块。所以在那个内存块中,根本找不着privatePrint()这个函数。
可是?有人因为会问了?为什么如果在Parent中申明了一个虚函数类型的privatePrint()就可以了呢?
还记得类的实例在内存中加载的那个图吗?每个类的前面都有一个的vPtr虚函数指针,他指向的是当前类的虚函数表。通过虚函数表中的privatePrint()也相当一个指针,指向了子类中实现父类虚函数的privatePrint(),自然就能找到了。
关注天下网吧微信,了解网吧网咖经营管理,安装维护: