我们时常在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\n);  
}  
void EditFunc()  
{  
   printf(EditFunc\n);  
}  
程序输出为:  
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, 0, sizeof (_thread);  
    memset(&_threadAttributes, 0, sizeof (_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;  
}   

【转】 C++易混知识点2. 函数指针和指针函数的区别的更多相关文章

  1. 【转】C++易混知识点1: 指针常量和常量指针的区别,附有详细案例解释

    熟悉C++也已经有一些年头了,今天突然翻出当年浏览的书籍,对一些概念居然生疏了,指针常量和常量指针由于 指针 这一特殊的对象而变得难以区别.因此,在思考再三之后,决定写下该篇总结,加强对他们的区别: ...

  2. 【转】C++易混知识点3. New Operator, Operator New, Placement New 实例分析,比较区别

    我们知道,C++中引入了New 这个内置符号,很大方便了指针的使用,程序员不必关注与这块堆上新分配的内存是如何来的,如何初始化的,然后如何转换为我们想要的类型指针的.现在,我们重点来分析下这个NEW内 ...

  3. 【转】 C++易混知识点4: 自己编写一个智能指针(Reference Counting)学习auto_ptr和reference counting

    这篇文章建大的介绍了如何编写一个智能指针. 介绍: 什么是智能指针?答案想必大家都知道,智能指针的目的就是更好的管理好内存和动态分配的资源,智能指针是一个智能的指针,顾名思义,他可以帮助我们管理内存. ...

  4. 【转】C++易混知识点5:实例讲解Public Protected Private作用域,继承的区别和用意

    大学生涯,涉及到类的作用域,继承都是用的public 共有继承,当时也没想那么多,觉得共有继承多方便,多简单,反正没有太多的限制,不管是类的成员或者是基类的成员函数都可以访问.没有深究.其实这里面真是 ...

  5. 两个知识点的回顾(const指针和动态链接库函数dlopen)

    昨天,看了一点<c++ primer>和<程序员的自我修养>,想起了自己以前的两个知识点,这里回顾,并且总结一下. 1. const指针的参数 看primer的时候,看到几个概 ...

  6. C语言之数组与指针的易混淆知识点

    一.指针与数组 指针:指针本身也是一个变量,它的内容是指向的内容的地址.指针同样有类型的区分,char 的指针只能指向char型数据,int 指针指向int型数据.但是指针所占内存单元的大小(即其内容 ...

  7. C语言基础知识点整理(函数/变量/常量/指针/数组/结构体)

    函数 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ...

  8. C++之易混淆知识点四---虚函数与虚继承

    C++面向对象中,虚函数与虚继承是两个完全不同的概念. 一.虚函数 C++程序中只要类中含有虚拟函数,编译程序都会为此类生成一个对应的虚拟函数跳转表(vtbl),该虚拟函数跳转表是一个又若干个虚拟函数 ...

  9. python函数-易错知识点

    定义函数: def greet_users(names): #names是形参 """Print a simple greeting to each user in th ...

随机推荐

  1. Vue + iView + vuex + vee-validate 完整项目总结

    build/*.js config/*.js src/旧代码文件夹 部门最近的一个新项目启动,很幸运由我来主导整个前端部分的技术选型和整体架构,项目工作量很大,但是却没有足够的人手,只有三个连CSS都 ...

  2. ARM非对齐操作异常解决过程

    在测试MF固件时,发生一个非常诡异的异常,代码如下: CLR_DBG_Commands::Monitor_EraseMemory* cmd = (CLR_DBG_Commands::Monitor_E ...

  3. 【转载】Centos7 中使用Supervisor守护进程

    配置supervisor实现进程守护 1.安装supervisor yum install Supervisor   2.启动服务 supervisord -c /etc/supervisord.co ...

  4. HTML基础知识(表格、表单)

    6.表格 l  概念:表格一定具有行和列 注:使用<thead><tbody><tfoot>,使浏览器能独立于表格表头和表格页脚的表格主体滚动.当包含多个页面的表格 ...

  5. 关于构造函数和原型prototype对象的理解

    构造函数     1.什么是构造函数 构造函数,主要用于对象创建的初始化,和new运算符一起用于创建对象,一个类可以有多个构造函数,因为函数名相同,所以只能通过参数的个数和类型不同进行区分,即构造函数 ...

  6. 降维之pca算法

    pca算法: 算法原理: pca利用的两个维度之间的关系和协方差成正比,协方差为0时,表示这两个维度无关,如果协方差越大这表明两个维度之间相关性越大,因而降维的时候, 都是找协方差最大的. 将XX中的 ...

  7. CSS3让文本自动换行——word-break属性

    1.依靠浏览器让文本自动换行 浏览器本身都自带着让文本自动换行的功能. 2.指定自动换行的处理方法 在CSS3中,可以使用word-break属性来自己决定自动换行的处理方法. div{ word-b ...

  8. linux(三)之linux常用命令二

    今天就是星期五了,又可以休息两天了.有点小激动,开心.不过还是要加油,因为还有很多东西等着我去学习呢! 七.chmod 作用:修改文件的权限 7.1.命令格式:chmod mode filename ...

  9. Codeforces 791B Bear and Friendship Condition(DFS,有向图)

    B. Bear and Friendship Condition time limit per test:1 second memory limit per test:256 megabytes in ...

  10. C语言缓冲区(缓存)详解

    缓冲区又称为缓存,它是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区.缓冲区根据其对应的是输入设备还是输出设备,分为输 ...