zoukankan      html  css  js  c++  java
  • C++继承类和基类之间成员函数和虚函数调用机制

    今天去参加百度的面试,遇到一个关于虚函数的机制的问题,我一直认为就是为了让基类指针或引用(指向继承类)能够看到基类的虚函数(当基类的虚函数没有被继承类重写),但是继承类又怎么看到基类的普通成员函数呢?我开始想,好想不可以调用基类的成员函数,因为基类的成员函数不是虚函数,在虚表找不到它,好吧,明天被鄙视了。回到家好好的研究了一下虚函数和成员函数,看看基类的成员函数和虚函数在派生类指针或引用是否可见,还有基类的成员函数和虚函数在基类指针或引用(指向继承类)是否可见,以及派生类的成员函数和虚函数在基类指针或引用(指向继承类)是否可见?

    下面是例子:

    #include <iostream>

    using namespace std;

    class A
    {
    public:
        A(int i) { n=i; }
        A(){ n=1;}
        virtual void f(){ std::cout<<"A.f() is used"<<endl;}
        void g(){ std::cout<<"A.g() is used"<<endl;}
        void k(){ std::cout<<"A.k() is used"<<endl;}

    private:
        int n;

    };

    class B:public A
    {
    public:
        B(int i) { n=i; }
        B(){ n=1;}
        void f(){ std::cout<<"B.f() is used"<<endl;}
        void g(){ std::cout<<"B.g() is used"<<endl;}
        void h(){ std::cout<<"B.h() is used"<<endl;}
        virtual void j(){ std::cout<<"B.h() is used"<<endl;}

    private:
        int n;
    };

    class C
    {
    public:
        C(int i) { n=i; }
        C(){ n=1;}
        void w(){ std::cout<<"C.w() is used"<<endl;}

    private:
        int n;
    };

    int main()
    {
        B b;
        b.k();   //b显然能看到A中的k()
        A *a;
        a=&b;
        a->f(); //a看到的是B的f()
        a->A::f();  //a看到的是A的f()
        a->g();  //a看到的是A的g()
        a->h();  //a看不到B的h()
        a->j();  //a看不到B的虚拟函数j()
        cout<<a->C::n<<endl;  //看不到
        a->C::w();  //看不到
        while(1)
        {
        }
    }

    一个类的对象中是没有关于普通成员函数的指针的slot,只有成员变量还有虚表指针,类的成员函数的代码定义在PE文件的代码区,所以从程序加载时,就已经分配好了内存用于存放这些代码;代码运行时所需要的内存,比如栈、堆等等,则是代码运行时才分配的;对于某个类的所有对象来说,类成员函数只在内存中有一份拷贝,所有的对象都共享同一份成员函数的代码。同一个类的不同的对象之间的差异仅仅是通过成员变量来体现的。c++实现成员函数的时候实际上用到了一个技巧——this指针。this指针是当前调用成员函数的对象首地址,我们知道通过这个地址可以访问到对应对象的成员变量。那么成员函数如何区分this究竟指向哪个对象呢?技巧就在于,c++背后把成员函数当做普通函数一样调用,除了传入实际的参数外,还把所属对象的指针作为参数this传入,函数内部通过显示的或者隐含的方式访问对象成员。当然,这只是背后的事情,外面用起来就和你见到的一样,简单直观。

    http://bbs.csdn.net/topics/80228792

    http://blog.csdn.net/haoel/article/details/1948051

  • 相关阅读:
    Luogu P4727-- 【HNOI2009】图的同构记数
    UOJ #390. 【UNR #3】百鸽笼
    Loj #2541「PKUWC2018」猎人杀
    BZOJ 1444:[JSOI2009]有趣的游戏
    CF895C: Square Subsets && 【BZOJ2844】albus就是要第一个出场
    [NOI2011]阿狸的打字机
    不要再搜啦,满足你的需要,封装保留小数点后两位
    react 中刷新,路由传参数丢失不存在了?
    字符串根据某个符号查找并截取
    react-swiper 如何实现滑动小卡片的移动?
  • 原文地址:https://www.cnblogs.com/GODYCA/p/2783408.html
Copyright © 2011-2022 走看看