没做过编译器就是被人欺——从一道变态的类型转换题猜编译器的行为(指针直接调用自己的非虚函数,当时是什么类型就是什么,但数据成员仍用自己的)

今天在群里看到一道题,有点意思:

#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.

posted @ 2015-08-12 21:46  findumars  Views(230)  Comments(0Edit  收藏  举报