zoukankan      html  css  js  c++  java
  • 【转】 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;  
    }  

  • 相关阅读:
    MVC ORM 架构
    Kubernetes 第八章 Pod 控制器
    Kubernetes 第七章 Configure Liveness and Readiness Probes
    Kubernetes 第六章 pod 资源对象
    Kubernetes 第五章 YAML
    Kubernetes 核心组件
    Kubernetes 架构原理
    Kubernetes 第四章 kubectl
    Kubernetes 第三章 kubeadm
    yum 配置及yum 源配置
  • 原文地址:https://www.cnblogs.com/xiongyunqi/p/4389562.html
Copyright © 2011-2022 走看看