虚函数指针深入理解

程序1

#include <iostream>

using namespace std;

class Base1

{

public:

    Base1()

    {

        m_length=1;

        m_width=2;

    }

    virtual void f(void)

    {

        cout<<"Base1::f()"<<endl;

    }

    virtual void g(void)

    {

        cout<<"Base1::g()"<<endl;

    }

    virtual void h(void)

    {

        cout<<"Base1::h()"<<endl;

    }

private:

    int m_length;

    int m_width;

};

class Base2

{

public:

    Base2()

    {

        m_length=3;

        m_width=4;

    }

    virtual void f(void)

    {

        cout<<"Base2::f()"<<endl;

    }

    virtual void g(void)

    {

        cout<<"Base2::g()"<<endl;

    }

    virtual void h(void)

    {

        cout<<"Base2::h()"<<endl;

    }

private:

    int m_length;

    int m_width;

};

class Derived:public Base1,public Base2

{

public:

    virtual void f(void)

    {

        cout<<"Derived::f()"<<endl;

    }

    virtual void k(void)

    {

        cout<<"Derived::k()"<<endl;

    }

};

int main()

{

    typedef void (*FUN)(void );

    FUN func=NULL;

    Derived d;

    cout<<"member table address "<<(int*)(&d)<<endl;

    cout<<"data member are follows:"<<endl;

    cout<<*((int*)(&d)+1)<<endl;

    cout<<*((int*)(&d)+2)<<endl;

    cout<<*((int*)(&d)+4)<<endl;

    cout<<*((int*)(&d)+5)<<endl;

    cout<<"The two vptr address:"<<endl;

    cout<<"the first vptr address "<<((int*)&d)<<endl;

    func=(FUN)*((int*)*((int*)(&d)));

    func();

    func=(FUN)*((int*)*(int*)(&d)+1);

    func();

    func=(FUN)*((int*)*(int*)(&d)+2);

    func();

    func=(FUN)*((int*)*(int*)(&d)+3);

    func();

    cout<<endl;

    cout<<"the second vptr address "<<(int*)&d+3<<endl;

    func=(FUN)*((int*)*((int*)(&d)+3));

    func();

    func=(FUN)*((int*)*((int*)(&d)+3)+1);

    func();

    func=(FUN)*((int*)*((int*)(&d)+3)+2);

    func();

    func=(FUN)*((int*)*((int*)(&d)+3)+3);

    func();     //运行时出错,非法访问,derived::k存放在Base1的虚函数表中

    return 0;

}

运行结果:

member table address 0x22ff40

data member are follows:

1

2

3

4

The two vptr address:

the first vptr address 0x22ff40

Derived::f()

Base1::g()

Base1::h()

Derived::k()

the second vptr address 0x22ff4c

Derived::f()

Base2::g()

Base2::h()

Process returned -1073741819 (0xC0000005)   execution time : 2.531 s

Press any key to continue.

程序2

#include <iostream>

using namespace std;

class Base1

{

public:

    Base1()

    {

        m_length=1;

        m_width=2;

    }

    virtual void f(void)

    {

        cout<<"Base1::f()"<<endl;

    }

    virtual void g(void)

    {

        cout<<"Base1::g()"<<endl;

    }

    virtual void h(void)

    {

        cout<<"Base1::h()"<<endl;

    }

private:

    int m_length;

    int m_width;

};

class Base2

{

public:

    Base2()

    {

        m_length=3;

        m_width=4;

    }

    virtual void f(void)

    {

        cout<<"Base2::f()"<<endl;

    }

    virtual void g(void)

    {

        cout<<"Base2::g()"<<endl;

    }

    virtual void h(void)

    {

        cout<<"Base2::h()"<<endl;

    }

private:

    int m_length;

    int m_width;

};

class Derived:public Base2,public Base1            /*修改处*/

{

public:

    virtual void f(void)

    {

        cout<<"Derived::f()"<<endl;

    }

    virtual void k(void)

    {

        cout<<"Derived::k()"<<endl;

    }

};

int main()

{

    typedef void (*FUN)(void );

    FUN func=NULL;

    Derived d;

    cout<<"member table address "<<(int*)(&d)<<endl;

    cout<<"data member are follows:"<<endl;

    cout<<*((int*)(&d)+1)<<endl;

    cout<<*((int*)(&d)+2)<<endl;

    cout<<*((int*)(&d)+4)<<endl;

    cout<<*((int*)(&d)+5)<<endl;

    cout<<"The two vptr address:"<<endl;

    cout<<"the first vptr address "<<((int*)&d)<<endl;

    func=(FUN)*((int*)*((int*)(&d)));

    func();

    func=(FUN)*((int*)*(int*)(&d)+1);

    func();

    func=(FUN)*((int*)*(int*)(&d)+2);

    func();

    func=(FUN)*((int*)*(int*)(&d)+3);

    func();

    cout<<endl;

    cout<<"the second vptr address "<<(int*)&d+3<<endl;

    func=(FUN)*((int*)*((int*)(&d)+3));

    func();

    func=(FUN)*((int*)*((int*)(&d)+3)+1);

    func();

    func=(FUN)*((int*)*((int*)(&d)+3)+2);

    func();

    func=(FUN)*((int*)*((int*)(&d)+3)+3);

    func();  //运行时出错,非法访问,derived::k存放在Base2的虚函数表中

    return 0;

}

运行结果:

member table address 0x22ff40

data member are follows:

3

4

1

2

The two vptr address:

the first vptr address 0x22ff40

Derived::f()

Base2::g()

Base2::h()

Derived::k()

the second vptr address 0x22ff4c

Derived::f()

Base1::g()

Base1::h()

Process returned -1073741819 (0xC0000005)   execution time : 1.343 s

Press any key to continue.

根据运行结果可以得到如下结论:

(1) 派生类中的数据成员是按照对父类的继承顺序确定的。

(2) 虚函数指针在用户成员表中是按下图来存储的。

 (3) 在派生类中新建的虚成员函数存放在所继承的第一个虚基类的虚函数表中。

                 程序1                 程序2

vptr1

  vptr2

1

   3

2

   4

vptr2

  vptr1

3

   1

4

   2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值