• 【转】 C++易混知识点2. 函数指针和指针函数的区别


    我们时常在C++开发中用到指针,指针的好处是开销很小,可以很方便的用来实现想要的功能,当然,这里也要涉及到指针的一些基本概念。指针不是基本数据类型,我们可以理解他为一种特殊类型的对象,他占据一定空间,但是所带来的好处就是C++如此强大的深层次原因了。


    转载请注明出处: http://blog.csdn.net/elfprincexu


    1. 指针函数, ( __type__ * func( void, int,) )


    顾名思义,他是一个函数,只不过和一般函数区分的原因是它返回的是一个指针。
    int* f ( int , int ) ; // 返回的是一个整形指针
    int  f ( int, int);// 返回的是一个整形数
    上面两个区别的仅仅是返回值得不同,(注意顺便说下,返回值不同可不是重载函数,重载函数只根据形参的类型和个数,当然,只读函数const也是重载函数的判断依据)
    当然,指针函数在使用时,必须与调用者的类型相同, 也就是说,返回值必须和左值的类型相同。
    int * a = f (5,67) ; // 合法,类型相同
    总结: 指针函数,比较容易懂,和一般函数的区别仅仅是返回值得不同,调用时注意返回的类型指针。


    2. 函数指针 (__type__ (* func)(void*, int))


    函数指针,顾名思义,还是一个指针,只不过这个指针比较特殊,他和其他函数名一样,具有(返回值类型,形参个数和类型)

    int (*pFunc) (int , float) ;  // 合法,定义了一个函数指针pFunc,该函数指针具有 返回int类型,同时带有两个形参,一个是int, 另一个是float;

    我们可以简单理解为函数指针和一般的函数名一样,其实,一般情况下,函数名所代表的含义就是一个函数入口地址(指针)。 

    int getSum (int a, float b);

    pFunc = getSum;//合法,函数名也可以理解为指针

    pFunc = &getSum;  // 合法,& 去地址符可以省略

    int x = (*pFunc)(3,50;// 合法,使用函数指针调用时,我们需要用挂号将它包围使用,

    void (*funcp)();  
    void FileFunc(),EditFunc();  
    main()  
    {  
       funcp=FileFunc;  
      (*funcp)();  
      funcp=EditFunc;  
      (*funcp)();  
    }  
    void FileFunc()  
    {  
       printf(FileFunc );  
    }  
    void EditFunc()  
    {  
       printf(EditFunc );  
    }  
    程序输出为:  
    FileFunc  
    EditFunc  


    总结: 函数指针,本质是指针,不过代表的是一个函数入口地址,我们可以用该指针灵活的使用不同的函数。


    在一般情况下,函数指针比较常用,他可以灵活的使用不同的函数来实现我们想要的结果。比如在常见的C++应用中,我们往往会定义一个函数指针,该函数指针通过继承来实现不同的实现。

    class ThreadUser  
    {     
        public:  
        typedef void (ThreadUser::*EntryPtr)(void * arg)    ;// 定义了一个函数指针EntryPtr, 参数为无类型指针,返回值为空值void  
    }  
    class Thread  

    {  
        public:  
        Thread(ThreadUser&, ThreadUser::EntryPtr, void* arg = 0 );  
        ...  
        private:  
        pthread_t _thread;  
        pthread_attr_t _threadAtrributes;  
        Thread::EntryPt _entry;  
        ThreadUser* _user;  
        bool    _done; void * _arg;  
        static void entry(Thread&);// 线程入口函数  
        static int _threadCount;  
    }  

    义:  
    // 定义另一个函数指针,为pthread_create服务,pthread_create 线程入口函数start_rtn需要此类型函数  

    typedef void* (*EntryPoint)(void*); Thread::Thread(ThreadUser& u, ThreadUser::EntryPtr e, void* arg ) : _entry(e), _user(&u), _done(false), _arg(arg)   

    {  
        memset (&_thread, 0sizeof (_thread);  
        memset(&_threadAttributes, 0sizeof (_threadAttributes);  
        int thrCreateResult;  
        if ((thrCreateResult = pthread_create(&_thread,&_threadAttributes, (EntryPoint)entry, this)) != 0// this 作为入口函数的argu  
        {  
            cerr << "pthread_create failed " << errno << endl;  
        }  
        else   
        {  
            _started = true;  
            _threadCount ++;  
        }  
        return true;  
    }  
      
    void Thread::entry(Thread& t)// 入口函数,形参为Thread 对象,在上面this  
    {  
        (t._user->*t._entry)(t._arg);            // 调用该函数指针所指向的函数  
        t._done = true;  
    }  

  • 相关阅读:
    史上最全Java表单验证封装类
    QQ组件可导致IE10无响应
    如何获取特定用户组内的无效账户?
    IN2Windows 8 (Part 2)
    IN2Windows 8 (Part 4) 文件历史记录功能及其重置方法
    IN2Windows 8 (Part 3)
    Android 多文件监听的实现
    Android 调用打电话,发短信(彩信),发邮件,浏览器,分享,跳转系统的各个设置页面
    Android中Drawable小结
    Android 加载.gif格式图片
  • 原文地址:https://www.cnblogs.com/xiongyunqi/p/4389562.html
Copyright © 2020-2023  润新知