C++成员函数指针与其应用场景

来源:互联网 发布:windows永久免费vps 编辑:程序博客网 时间:2024/06/15 13:45

<span style="font-size:18px;">//成员函数指针#include <iostream>using namespace std;//全局函数void test (){    cout << "this is test" << endl;}void test2 (int a){    cout << "this is test22222" << endl;}//结构体struct Date{    int year;    int month;    int day;    //成员函数    void show(){        cout << year << ' ' << month << ' ' << day << endl;    }    //有参    void show2(int a,int b){        cout << "这是有参的成员函数" << endl;        cout << year << '-' << month << '-' << day << ' ' << a+b << endl;    }        //无参    void showYear(){        cout << "今年是 " << year << " 年!" << endl;    }            int add(){        return year + month + day;    }    int sub(){        return year - month - day;    }    };//这样相当于间接调用了void addFunc(Date d){    cout << "年月日的和为: " << d.add() << endl;;}void subFunc(Date d){    cout << "年月日的差为: " << d.sub() << endl;;}typedef int (Date::*Func3)();//返回值是int 参数为空的成员函数指针的别名void setFunc(Date d,Func3 f){//如果想执行加的方法 那么只要传进那个加的成员函数的地址就可以了  同理减法的也是一样    cout << (d.*f)() << endl;}//这是给int类型起别名 叫做 Ttypedef int T;//给函数指针起别名typedef void (*Func)(int); //注意 这和int的起别名不一样  这个整体void (*)(int)是类型 ,Func是这个类型的别名   其实和int的别名还是一样的原理,只是不支持那种格式 typedef void (*)(int) Func; //不支持这种语法//给成员函数指针起别名typedef void (Date::*Func2)(); //这个指针 只要是Date这个类里面的 没有返回值 也没有参数的 成员函数 都可以指向//主函数int main(){    #pragma 全局函数的    //可以声明一个函数指针指向这个全局函数 然后通过调用函数指针来调用这个全局函数    #pragma 声明 函数指针变量  这是无参的函数指针    //函数指针比较特别  整个是它的类型void (*)()    指针变量名是 f    void (*f)();//如果(*f)没有加括号  编译器会以为我们的返回值是void *        //指向全局函数     全局函数的函数名 就是函数指针    f = test; //如果这个全局函数带参数 那么这个函数指针就不合适了(类型不匹配)    f();        #pragma 声明有参数的 函数指针    void (*f2)(int);    f2 = test2;    //通过函数指针来调用函数    f2(100);//随便给个参数                /*     很多时候 我们可以声明很多个int类型的变量 同理,如果我们想要声明很多个 函数指针变量的话 ,那岂不是要写很多次这样的     void (*f2)(int);       void (*f3)(int);      .....      void (*f9)(int);          */#pragma 这样的情况 我们会给函数指针类型 起一个 别名    //例如给int类型起别名叫T  那么可以通过T来声明变量    T a;    a = 10;    cout << "这是通过起别名来声明的int类型 a = " << a << endl;        //用函数指针的别名 声明变量    Func f3;    f3 = test2;    f3(100);                /*     *     *          现在我要声明一个函数指针 指向 成员函数     那么我们首先得把那个成员函数的地址取出来 (对于全局函数而言,函数名就是地址)  但是成员函数不一样          *     *     */    #pragma 获取成员函数地址    // &类型名::成员函数名称     (对象的类型里面就是:类或者结构. 在这里就是类名,或者结构体的名称)    &Date::show;        /*         //声明一个函数指针  指向一个没有参数的函数    void (*funct)();        //不能直接指向成员函数 因为类型不匹配  也就是说这个函数指针指向的好似全局函数    funct = &Date::show;         */    #pragma 声明无参 成员函数指针    //函数返回值类型  (类名::成员函数指针变量名称)(参数)    void (Date::*funct)();    funct  = &Date::show;  //这样就可以指向 成员函数了        //这个指针指向的是成员函数   现在没有对象所以不能直接调用    //funct();        //要调用成员函数 必须有成员    Date d = {2013,1,10};        //通过对象 调用 成员函数指针 访问到 成员函数        cout << "对象 调用 成员函数 是点.语法" << endl;    d.show();        cout << "那么通过 函数指针 调用 成员函数  如何??" << endl;    //d.*funct();//这里有优先级问题 把后面看一个整体了funct()    (d.*funct)();            cout << "=================" << endl;#pragma 通过别名声明的 无参的成员函数指针    Func2 fb;    fb = &Date::showYear;  //在这里也可以让前面定义的 funct指向showYear  因为是指针    (d.*fb)();            cout << "=================" << endl;#pragma 声明有参的  成员函数指针    //返回值类型  (类名::成员函数指针变量名)(参数)    void (Date::*funct2)(int,int);    funct2 = &Date::show2;//取成员函数地址    //调用    (d.*funct2)(100,200);        //应用场景    //有两个成员方法  add  sub  可以通过结构体对象去调用可以实现逻辑 ,但是我不想在main方法里面调用,所以在外面定义一个全局函数来包装    addFunc(d);    subFunc(d);        /*     问题来了,如果我有加减乘除求余等等很多方法  那岂不是要写很多个全局函数?          现在我要把这两个方法封装成一个方法  ,它们不同之处在于调用的方法不一样     */        cout << "成员函数指针的应用场景" << endl;    setFunc(d, &Date::sub);        /*     我还是觉得这样麻烦 传参数每次都要带 &Date::       可以用宏替换  宏函数     */    cout << "宏替换之后的成员函数指针的应用场景" << endl;#define selector(SET) (&Date::SET)  //SET是宏参数    setFunc(d, selector(add));        return 0;}</span>


0 0
原创粉丝点击