【转】 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\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;  
}

时间: 2024-10-08 16:37:16

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

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

我们知道,C++中引入了New 这个内置符号,很大方便了指针的使用,程序员不必关注与这块堆上新分配的内存是如何来的,如何初始化的,然后如何转换为我们想要的类型指针的.现在,我们重点来分析下这个NEW内置符号背后的步骤和所调用到的函数.这里面涉及到new operator, operator new, placement new. 转载请注明出处: http://blog.csdn.net/elfprincexu 1. New Operator (__type__ * a = new a();)

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

大学生涯,涉及到类的作用域,继承都是用的public 共有继承,当时也没想那么多,觉得共有继承多方便,多简单,反正没有太多的限制,不管是类的成员或者是基类的成员函数都可以访问.没有深究.其实这里面真是涉及到了C++面向对象设计当中的封装特性.只暴露那些需要的成员和成员函数,不必过多曝露所有的成员. 转载请注明出处:http://blog.csdn.net/elfprincexu 第一:private.public.protected访问的范围. private:只能由1.该类中的函数:2.其友元

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

这篇文章建大的介绍了如何编写一个智能指针. 介绍: 什么是智能指针?答案想必大家都知道,智能指针的目的就是更好的管理好内存和动态分配的资源,智能指针是一个智能的指针,顾名思义,他可以帮助我们管理内存.不必担心内存泄露的问题.实际上,智能指针是一个行为类似于指针的类,通过这个类我们来管理动态内存的分配和销毁.方便客户端的使用.相比于一般指针,智能指针主要体现在它使用的容易和便捷性. 转载请注明出处: http://blog.csdn.net/elfprincexu 使用一般指针的问题: 一般情况下

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

C++面向对象中,虚函数与虚继承是两个完全不同的概念. 一.虚函数 C++程序中只要类中含有虚拟函数,编译程序都会为此类生成一个对应的虚拟函数跳转表(vtbl),该虚拟函数跳转表是一个又若干个虚拟函数体入口地址组成的一个线性表.派生类的虚拟函数跳转表的前半部分由父类的vtbl得出,但是里面的内容不一定相同,后半部分则对应着自己新定义的虚拟函数. class Employee { protected: char *Name; int Age; public: void changeAge(int

C语言指针与数组易混淆知识点(一)

一指针与数组 二指针与函数 三指针数组数组指针指向指针的指针 四程序陷阱 一.指针与数组 指针:指针本身也是一个变量,它的内容是指向的内容的地址.指针同样有类型的区分,char 的指针只能指向char型数据,int 指针指向int型数据.但是指针所占内存单元的大小(即其内容)是跟操作系统的地址位数有关,比如32位地址的系统,那么指针所占的内存单元就是4个字节,16位就是2个字节,因此,指针的类型只是限定它所指向的变量的类型,其内容所占的单元大小是与操作系统的地址位数相关,与变量类型无关. 在32

指针易混点

C++最强大的地方之一在于指针. 关于指针,首先我来说一下,它的好处. 好处一,用指针传递数据,节省空间和时间 好处二,可以动态的创建数组,也就是说在程序编译的时候创建内存空间. 比如说: int length; cin>>length; int * A = new int[length]; 以上代码是正确的,而且也很节省空间,用多少就开多少空间.与之相对立的是静态编译,在程序执行之前就已经将空间定下来,如果把最后一行改成int A[length]是通不过,因为程序执行之前需要确定数组的大小.

C++之易混淆知识点一

1.const.mutable与volatile的区别:const表明内存被初始化以后,程序将不能对它进行修改.volatile则表明,即使程序代码没有对内存单元进行修改,但是里面的值也可能会发生变化.例如:将一个指针指向某个硬件位置,其中包含了来自串行端口的时间和信息,在某些情况下,硬件而不是程序可能会修改其中的内容,或者两个程序可能相互影响,共享数据.该关键字的作用就是为了改善编译器的优化能力.假设编译器发现程序在几条语句中两次使用某个变量的值,则编译器可能不是让程序查找这个编码的值两次,而

常问易混淆知识点(嵌入式)

b 一.知识点1 a) 关键字volatile在编译时有什么含义?并给出三个不同使用场景的例子(可以伪代码或者文字描述).b) C语言中static关键字的具体作用有哪些 ?c) 请问下面三种变量声明有何区别?请给出具体含义int const *p;int* const p;int const* const p; a) 用volatile关键字定义变量,相当于告诉编译器,这个变量的值会随时发生变化,每次使用时都需要去内存里 重新读取它的值,并不要随意针对它作优化. 建议使用volatile变量的

Javascript易错知识点

? JS易错知识点总结: == 和 === 的区别: ==:判断两个变量的值是否相等. ===:判断两个变量的类型和值是否都相等,两个条件同时满足时,表达式为True. switch中break的作用: 如果一个case后面的语句,没有写break,那么程序会向下执行,而不会退出: 例如:当满足条件的case 2下面没有break时,case 3也会执行 1 var num = 2; 2 switch(num){ 3 case 1: 4 alert('case 1'); 5 break; 6 c