没做过编译器就是被人欺——从一道变态的类型转换题猜编译器的行为(指针直接调用自己的非虚函数,当时是什么类型就是什么,但数据成员仍用自己的)
今天在群里看到一道题,有点意思:
#include "mainwindow.h" #include <QApplication> #include <iostream> using namespace std; class A{ public : A(){m_f1=1;} int m_f1; void fun(){ cout<<"A"<<m_f1<<endl; } }; class B{ public: B(){m_f2=2;} int m_f2; void fun() { cout<<"B"<<m_f2<<endl; } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); A m; B* pb; pb=(B*)(&m); pb->fun(); return a.exec(); }
输出结果是:B1
解释原因已经写在标题里了,本类也没什么可说的,但是为了加深印象,不如再仔细说一下把:一旦编译器生成了代码,函数的执行体是固定位置,因此可随意被调用,所以才会发生B->fun()调用的时候,直接去调用B的fun()函数这种事情(前提是fun是非虚函数),即使这个B指针是转换而来。即使A不做转换调用自己的类函数,也是需要跳转才能调用的,这两种调用方式在本质上没有任何区别(前提是非虚函数)。但是B的数据成员却仍是从A那里拿来的,所以它的数据成员仍是1.