C++中函数指针的运用

来源:互联网 发布:网络拓扑环形结构 编辑:程序博客网 时间:2024/06/05 03:46
/* * class_pointer.cxx * *  Created on: 2012-9-15 *      Author: Jesse Meng */  #include <iostream>using namespace std;class Base {public:    void foo1(void){cout<<"foo1"<<endl;}    void foo2(void){cout<<"foo2被调用啦,mem2的值是"<<this->mem2<<"!"<<endl;}    virtual void foo3(void){cout<<"foo3"<<endl;}    virtual void foo4(void){cout<<"foo4"<<endl;}    virtual void foo5(void){cout<<"foo5"<<endl;}     Base(int i){        cout<<"cons"<<endl;        this->f=&Base::foo2;        this->mem1=1.0;        this->mem2=i;    }    ~Base(){        cout<<"des"<<endl;    }     double mem1;    int mem2;    void (Base::*f)(void);}; void test(){cout<<"test函数被调用啦!"<<endl;}int main(int argc, char **argv) {    //这个例子不涉及继承的情况啦!!!!!      Base *b = new Base(1);    Base *b2 = new Base(2);    //声明的两个实例的位置    cout<<"第一个实例的地址是: "<<b<<endl<<"第二个实例的地址是: "<<b2<<endl;    //对成员取地址,&后加不加括号都一球样    cout<<"第一个实例mem1成员的地址是: "<<&b->mem1<<endl            <<"第一个实例mem2成员的地址是: "<<&b->mem2<<endl            <<"第一个实例f成员的地址是: "<<&b->f<<endl;    cout<<"第二个实例mem1成员的地址是: "<<&(b2->mem1)<<endl            <<"第二个实例mem2成员的地址是: "<<&(b2->mem2)<<endl            <<"第二个实例f成员的地址是: "<<&b2->f<<endl;    //再看下函数的地址,下面的输出回事1\n1,这是不对滴    //    void (Base::*fad)(void)=&Base::foo1;    cout<<"前面这个是错的"<<fad<<"| foo1的地址 "<<hex<<*(unsigned *)&fad<<endl;    fad=&Base::foo2;    cout<<"前面这个是错的"<<fad<<"| foo2的地址 "<<hex<<*(unsigned *)&fad<<endl;    fad=&Base::foo3;    cout<<"前面这个是错的"<<fad<<"| foo3的地址?! "<<hex<<*(unsigned *)&fad<<endl;    fad=&Base::foo4;    cout<<"前面这个是错的"<<fad<<"| foo4的地址?! "<<hex<<*(unsigned *)&fad<<endl;    fad=&Base::foo5;    cout<<"前面这个是错的"<<fad<<"| foo5的地址?! "<<hex<<*(unsigned *)&fad<<endl;    cout<<"类中的函数指针演示-----------------------"<<endl;    /*---------------下面来演示实例中的函数指针和类中方法是如何配合滴----------------------*/    //这是最普通的例子,木啥好说的    void (*t) ( )=test;    t();    //回顾一下类中的函数指针    void (Base::*f)(void);    (b->*b->f)();    //下面的调用过程可以这样来理解    //b2->f即通过b2获取实例中的函数指针,该指针指向类的方法    //需要通过一个实例来触发,前面的b即此时的实例    //所以此时输出的mem2的值为前面那个b中的值,即1    (b->*b2->f)();    (b2->*b->f)();    (b2->*b2->f)();    //前面的描述可以通过下面的代码来理解    void (Base::*f2)(void)=NULL;    f2=b2->f;    (b->*f2)();    cout<<"外部的函数指针演示-----------------------"<<endl;    /*---------------下面来演示外部的函数指针和类中方法是如何配合滴----------------------*/    //foo1,foo2调用方法和前面的类似    void (Base::*foo)(void) =&Base::foo1;    (b->*foo)();    cout<<"foo1的地址是: "<<hex<<(&Base::foo1)<<"    "<<*(unsigned *)&foo<<endl;    foo=&Base::foo2;    (b->*foo)();    cout<<"foo2的地址是: "<<hex<<(&Base::foo2)<<"    "<<(unsigned *)&foo<<endl;    //foo3,foo4的地址获取方法    unsigned int offset=0;    foo=&Base::foo3;    offset=*(unsigned *)&foo;    cout<<"foo3(虚)方法的偏移量(未修正) : "<<offset<<endl;    //我也不清楚三个虚方法的偏移量为1,5,9?!!!!!    //这里仅仅是修正一下    offset/=4;//1/4    //调用foo3方法    (b->*foo)();    //通过foo2来确定,用虚表加偏移地址然后调用的一致性    void (Base::*foo2)(void)=0;    //不带继承的情况下实例首地址存放虚表指针,可用"*(unsigned**)b+偏移量"的形式获取    foo2=*((void (Base::**)(void))(*(unsigned**)b+ offset));    cout<<"!!!!"<<endl;    (b->*foo2)();    cout<<"foo3的地址是: "<<hex<<*(unsigned *)&foo<<"    "<<*(unsigned**)b+offset<<endl;      foo=&Base::foo4;    offset=*(unsigned *)&foo;    cout<<"foo4(虚)方法的偏移量(未修正) : "<<offset<<endl;    offset/=4;//5/4    (b->*foo)();    cout<<*(unsigned *)&foo<<endl;    foo2=*((void (Base::**)(void))(*(unsigned**)b+ offset));    (b2->*foo2)();    cout<<"foo4的地址是: "<<hex<<*(unsigned *)&foo<<"    "<<*(unsigned**)b2+offset<<endl;      foo=&Base::foo5;    offset=*(unsigned *)&foo;    cout<<"foo5(虚)方法的偏移量(未修正) : "<<offset<<endl;    offset/=4;//9/4    (b->*foo)();    cout<<*(unsigned *)&foo<<endl;    foo2=*((void (Base::**)(void))(*(unsigned**)b+ offset));    (b2->*foo2)();    cout<<"foo5的地址是: "<<hex<<*(unsigned *)&foo<<"    "<<*(unsigned**)b2+offset<<endl;     delete b;    //b->~Base();    delete b2;    return 0;}

0 0
原创粉丝点击