打印

C++中的虚函数及其实现+代码

[复制链接]
1502|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
keer_zu|  楼主 | 2014-8-26 17:28 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
最近在做流媒体的应用,用的苹果的Darwin Streaming Server做二次开发,恶补一下C++。多态是C++的精髓。
C++中的虚函数是实现多态性的重要手段,它是通过虚函数表来实现的,虚函数表放在类的首地址位置,具体为:
*(int*)(&b) :其中b为一个类的实例(对象);

下面写的是对上面做出直观诠释的代码:
#include <iostream>
//单继承
class Base {
        public:
        int a,b,c;
        virtual void f() { std::cout << "Base::f" << std::endl; }
        virtual void g() { std::cout << "Base::g" <<std::endl; }
        virtual void h() { std::cout << "Base::h" << std::endl; }
};

class Derive:public Base
{
        public:
        virtual void f0() { std::cout << "Base::f0" << std::endl; }
        virtual void g0() { std::cout << "Base::g0" <<std::endl; }
        virtual void h0() { std::cout << "Base::h0" << std::endl; }
};

class Derive1:public Base
{
        public:
        virtual void f() { std::cout << "Base::f1" << std::endl; }
        virtual void g() { std::cout << "Base::g1" <<std::endl; }
        virtual void h() { std::cout << "Base::h1" << std::endl; }
};

//多继承的例子:
class Base1{
        public:
        int a,b,c;
        virtual void f() { std::cout << "Base1::f" << std::endl; }
        virtual void g() { std::cout << "Base1::g" <<std::endl; }
        virtual void h() { std::cout << "Base1::h" << std::endl; }
};

class Base2{
        public:
        int a,b,c;
        virtual void f() { std::cout << "Base2::f" << std::endl; }
        virtual void g() { std::cout << "Base2::g" <<std::endl; }
        virtual void h() { std::cout << "Base2::h" << std::endl; }
};

class Base3{
        public:
        int a,b,c;
        virtual void f() { std::cout << "Base3::f" << std::endl; }
        virtual void g() { std::cout << "Base3::g" <<std::endl; }
        virtual void h() { std::cout << "Base3::h" << std::endl; }
};

class DeriveMulti:public Base1,public Base2,public Base3
{
        virtual void f() { std::cout << "DeriveMulti::f" << std::endl; }
//        virtual void g() { std::cout << "DeriveMulti::g" <<std::endl; }
//        virtual void h() { std::cout << "DeriveMulti::h" << std::endl; }
        virtual void mm() { std::cout << "DeriveMulti::mm" << std::endl; }
};
typedef void(*Fun)(void);

int main(void)
{
        Base b;
        Derive d;
        Derive1 d1;
        Fun pFun = NULL;

        Base *pb;
        Base1 *pb1;
        Base2 *pb2;
        Base3 *pb3;

        DeriveMulti *pdm;

        std::cout <<"\n\n@@@@ Base TEST @@@@@" << std::endl;

        std::cout << "虚函数表地址:" << *(int*)(&b) << std::endl;
        std::cout << "虚函数表 — 第一个函数地址:" << *(int*)*(int*)(&b) << std::endl;

        pFun = (Fun)*((int*)*(int*)(&b));
        pFun();
        pFun = (Fun)*((int*)*(int*)(&b)+2); // Base::g()
        pFun();
        pFun = (Fun)*((int*)*(int*)(&b)+4); // Base::h()
        pFun();

        b.f();
        b.g();
        b.h();

        std::cout <<"\n\n@@@@ Dervie TEST @@@@@" << std::endl;

        std::cout << "虚函数表地址:" << *(int*)(&d) << std::endl;
        std::cout << "虚函数表 — 第一个函数地址:" << *(int*)*(int*)(&d) << std::endl;

        pFun = (Fun)*((int*)*(int*)(&d));
        pFun();
        pFun = (Fun)*((int*)*(int*)(&d)+2); // Base::g()
        pFun();
        pFun = (Fun)*((int*)*(int*)(&d)+4); // Base::h()
        pFun();

        pFun = (Fun)*((int*)*(int*)(&d)+6); // Base::g()
        pFun();
        pFun = (Fun)*((int*)*(int*)(&d)+8); // Base::h()
        pFun();
        pFun = (Fun)*((int*)*(int*)(&d)+10); // Base::g()
        pFun();

        d.f();
        d.g();
        d.h();
        d.f0();
        d.g0();
        d.h0();

        std::cout <<"\n\n@@@@ Dervie 1 TEST @@@@@" << std::endl;

        std::cout << "虚函数表地址:" << *(int*)(&d1) << std::endl;
        std::cout << "虚函数表 — 第一个函数地址:" << *(int*)*(int*)(&d1) << std::endl;

        pFun = (Fun)*((int*)*(int*)(&d1));
        pFun();
        pFun = (Fun)*((int*)*(int*)(&d1)+2); // Base::g()
        pFun();
        pFun = (Fun)*((int*)*(int*)(&d1)+4); // Base::h()
        pFun();

        d1.f();
        d1.g();
        d1.h();

        std::cout <<"\n\n@@@@ Base pointer TEST @@@@@" << std::endl;
        pb = &b;

        pb->f();
        pb->g();
        pb->h();

        pb = &d;

        pb->f();
        pb->g();
        pb->h();


        pb = &d1;
        pb->f();
        pb->g();
        pb->h();

        std::cout <<"\n\n@@@@  multiple inheritance TEST @@@@@" << std::endl;
        pdm = new DeriveMulti();

        pb1 = pdm;
        pb1->f();
        pb1->g();
        pb1->h();

        pb2=pdm;
        pb2->f();
        pb2->g();
        pb2->h();

        pb3=pdm;
        pb3->f();
        pb3->g();
        pb3->h();


        return 0;
}

相关帖子

沙发
keer_zu|  楼主 | 2014-8-26 17:29 | 只看该作者
在linux下编译,运行结果为:




@@@@ Base TEST @@@@@
虚函数表地址:4200656
虚函数表 — 第一个函数地址:4198364
Base::f
Base::g
Base::h
Base::f
Base::g
Base::h


@@@@ Dervie TEST @@@@@
虚函数表地址:4200592
虚函数表 — 第一个函数地址:4198364
Base::f
Base::g
Base::h
Base::f0
Base::g0
Base::h0
Base::f
Base::g
Base::h
Base::f0
Base::g0
Base::h0


@@@@ Dervie 1 TEST @@@@@
虚函数表地址:4200528
虚函数表 — 第一个函数地址:4198616
Base::f1
Base::g1
Base::h1
Base::f1
Base::g1
Base::h1


@@@@ Base pointer TEST @@@@@
Base::f
Base::g
Base::h
Base::f
Base::g
Base::h
Base::f1
Base::g1
Base::h1


@@@@  multiple inheritance TEST @@@@@
DeriveMulti::f
Base1::g
Base1::h
DeriveMulti::f
Base2::g
Base2::h
DeriveMulti::f
Base3::g
Base3::h

使用特权

评论回复
板凳
keer_zu|  楼主 | 2014-8-27 11:05 | 只看该作者
第一个函数地址: *(int*)*(int*)(&d)

感觉到指针在C++中的表现了吗?

使用特权

评论回复
地板
keer_zu|  楼主 | 2014-8-27 15:42 | 只看该作者

Darwin streaming server里面事件和任务交互的类图。

使用特权

评论回复
5
warfid| | 2014-8-30 16:07 | 只看该作者
哥你写个注释呀

使用特权

评论回复
6
keer_zu|  楼主 | 2014-9-1 09:24 | 只看该作者
warfid 发表于 2014-8-30 16:07
哥你写个注释呀

把上面程序编译、调试一下就什么都明白了。注释实在是不需要啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq群:49734243 Email:zukeqiang@gmail.com

1349

主题

12426

帖子

53

粉丝